summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2021-06-08 23:07:28 +0200
committerBartosz Kosiorek <gang65@poczta.onet.pl>2021-06-09 20:19:27 +0200
commit01ded1e6d362dbcd7148334c6965d6ad00981d4a (patch)
tree589c45e2a1b8c46e1c03f4281e16caca397e8a38
parentfca7d50b17fae217bd34e9e6f5e3a8b0fda93833 (diff)
WMF tdf#55058 tdf#142722 Add implementation of BitBlt and StretchBlt
With previous implementation, only BitBlt record with 1 bit color depth was supported and StretchBlt was not implemented at all. With this commit the support for 1 bit, 24 bit and 32 bit, for both BitBlt and StretchBlt were added. Change-Id: I061b2beae8c2f143ddff9c8c8bb64bf52f4cf502 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116873 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
-rw-r--r--drawinglayer/source/tools/primitive2dxmldump.cxx16
-rw-r--r--emfio/qa/cppunit/emf/EmfImportTest.cxx82
-rw-r--r--emfio/qa/cppunit/wmf/data/TestBitBltStretchBlt.wmfbin0 -> 918 bytes
-rw-r--r--emfio/source/reader/wmfreader.cxx124
-rw-r--r--include/vcl/BitmapTools.hxx2
-rw-r--r--vcl/source/bitmap/BitmapTools.cxx15
6 files changed, 151 insertions, 88 deletions
diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 295c13fde6e9..9ed0e796fb01 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -228,8 +228,22 @@ void Primitive2dXmlDump::decomposeAndWrite(
rWriter.attribute("height", rSizePixel.getHeight());
rWriter.attribute("width", rSizePixel.getWidth());
- rWriter.attribute("checksum", aBitmapEx.GetChecksum());
+ rWriter.attribute("checksum", OString(std::to_string( aBitmapEx.GetChecksum() )));
+ for (tools::Long y=0; y<rSizePixel.getHeight(); y++)
+ {
+
+ rWriter.startElement("data");
+ OUString aBitmapData = "";
+ for (tools::Long x=0; x<rSizePixel.getHeight(); x++)
+ {
+ if (x !=0)
+ aBitmapData = aBitmapData + ",";
+ aBitmapData = aBitmapData + aBitmapEx.GetPixelColor(x, y).AsRGBHexString();
+ }
+ rWriter.attribute("row", aBitmapData);
+ rWriter.endElement();
+ }
rWriter.endElement();
}
break;
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index d949240a40b5..8c56190203b0 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -62,6 +62,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest:
void TestFillRegion();
void TestExtTextOutOpaqueAndClipTransform();
+ void TestBitBltStretchBltWMF();
void TestExtTextOutOpaqueAndClipWMF();
void TestPaletteWMF();
void TestRoundrectWMF();
@@ -96,6 +97,8 @@ public:
CPPUNIT_TEST(TestDrawPolyLine16WithClip);
CPPUNIT_TEST(TestFillRegion);
CPPUNIT_TEST(TestExtTextOutOpaqueAndClipTransform);
+
+ CPPUNIT_TEST(TestBitBltStretchBltWMF);
CPPUNIT_TEST(TestExtTextOutOpaqueAndClipWMF);
CPPUNIT_TEST(TestPaletteWMF);
CPPUNIT_TEST(TestRoundrectWMF);
@@ -511,7 +514,6 @@ void Test::TestPolylinetoCloseStroke()
"color", "#000000");
}
-
void Test::TestExtTextOutOpaqueAndClipTransform()
{
// tdf#142495 EMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUTW, MODIFYWORLDTRANSFORM, CREATEFONTINDIRECT.
@@ -521,7 +523,6 @@ void Test::TestExtTextOutOpaqueAndClipTransform()
xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
CPPUNIT_ASSERT (pDocument);
-
assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", 2);
assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion[1]",
"text", "No_rect- DLP-");
@@ -576,6 +577,73 @@ void Test::TestExtTextOutOpaqueAndClipTransform()
"fontcolor", "#000000");
}
+void Test::TestBitBltStretchBltWMF()
+{
+ // tdf#55058 tdf#142722 WMF records: BITBLT, STRETCHBLT.
+ Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/wmf/data/TestBitBltStretchBlt.wmf");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap", 2);
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "xy11", "508");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "xy12", "0");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "xy13", "711");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "xy21", "0");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "xy22", "508");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "xy23", "508");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "height", "10");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "width", "10");
+#if !defined(MACOSX) && !defined(_WIN32) // TODO Bitmap display needs to be aligned for macOS and Windows
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]",
+ "checksum", "747141214295528493");
+#endif
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]/data",
+ 10);
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]/data[1]",
+ "row", "000000,000000,000000,000000,000000,000000,000000,000000,000000,000000");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]/data[4]",
+ "row", "000000,ffffff,000000,ffffff,000000,ffffff,000000,ffffff,000000,ffffff");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[1]/data[5]",
+ "row", "ffffff,000000,ffffff,ffffff,000000,000000,000000,ffffff,ffffff,000000");
+
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "xy11", "1524");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "xy12", "0");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "xy13", "1524");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "xy21", "0");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "xy22", "1016");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "xy23", "102");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "height", "10");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "width", "10");
+#if !defined(MACOSX) && !defined(_WIN32) // TODO Bitmap display needs to be aligned for macOS and Windows
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]",
+ "checksum", "3134789313661517563");
+#endif
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]/data",
+ 10);
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]/data[1]",
+ "row", "000000,00001c,000038,000055,000071,00008d,0000aa,0000c6,0000e2,0000ff");
+ assertXPath(pDocument, "/primitive2D/metafile/transform/bitmap[2]/data[5]",
+ "row", "720000,721c1c,723838,725555,727171,72728d,55728d,39728d,1d728d,00728d");
+}
+
void Test::TestExtTextOutOpaqueAndClipWMF()
{
// tdf#53004 WMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUT, CREATEBRUSHINDIRECT.
@@ -713,10 +781,16 @@ void Test::TestStretchDIBWMF()
"height", "10");
assertXPath(pDocument, "/primitive2D/metafile/transform/mask/bitmap",
"width", "10");
-#if !defined(MACOSX) // TODO DIB display needs to be fixed for macOS
+#if !defined(MACOSX) // TODO DIB display needs to be aligned for macOS
assertXPath(pDocument, "/primitive2D/metafile/transform/mask/bitmap",
- "checksum", "275245357");
+ "checksum", "14148300367030905133");
#endif
+ assertXPath(pDocument, "/primitive2D/metafile/transform/mask/bitmap/data",
+ 10);
+ assertXPath(pDocument, "/primitive2D/metafile/transform//mask/bitmap/data[1]",
+ "row", "000000,00001c,000038,000055,000071,00008d,0000aa,0000c6,0000e2,0000ff");
+ assertXPath(pDocument, "/primitive2D/metafile/transform//mask/bitmap/data[5]",
+ "row", "720000,721c1c,723838,725555,727171,72728d,55728d,39728d,1d728d,00728d");
}
void Test::TestPolyLineWidth()
diff --git a/emfio/qa/cppunit/wmf/data/TestBitBltStretchBlt.wmf b/emfio/qa/cppunit/wmf/data/TestBitBltStretchBlt.wmf
new file mode 100644
index 000000000000..030027c7522e
--- /dev/null
+++ b/emfio/qa/cppunit/wmf/data/TestBitBltStretchBlt.wmf
Binary files differ
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index 65c2cff1f465..64dbf6658854 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -802,29 +802,19 @@ namespace emfio
break;
case W_META_BITBLT:
+ case W_META_STRETCHBLT:
{
- // 0-3 : nRasterOperation #93454#
- // 4-5 : y offset of source bitmap
- // 6-7 : x offset of source bitmap
- // 8-9 : height of source and destination bitmap
- // 10-11 : width of source and destination bitmap
- // 12-13 : destination position y (in pixel)
- // 14-15 : destination position x (in pixel)
- // 16-17 : bitmap type
- // 18-19 : Width Bitmap in Pixel
- // 20-21 : Height Bitmap in Pixel
- // 22-23 : bytes per scanline
- // 24 : planes
- // 25 : bitcount
-
sal_uInt32 nRasterOperation = 0;
- sal_Int16 nYSrc = 0, nXSrc = 0, nSye = 0, nSxe = 0, nBitmapType = 0, nWidth = 0, nHeight = 0, nBytesPerScan = 0;
+ sal_Int16 nSrcHeight = 0, nSrcWidth = 0, nYSrc, nXSrc, nSye, nSxe, nBitmapType, nWidth, nHeight, nBytesPerScan;
sal_uInt8 nPlanes, nBitCount;
const bool bNoSourceBitmap = ( nRecordSize == ( static_cast< sal_uInt32 >( nFunc ) >> 8 ) + 3 );
mpInputStream->ReadUInt32( nRasterOperation );
SAL_INFO("emfio", "\t\t Raster operation: 0x" << std::hex << nRasterOperation << std::dec << ", No source bitmap: " << bNoSourceBitmap);
+ if( nFunc == W_META_STRETCHBLT )
+ mpInputStream->ReadInt16( nSrcHeight ).ReadInt16( nSrcWidth );
+
mpInputStream->ReadInt16( nYSrc ).ReadInt16( nXSrc );
if ( bNoSourceBitmap )
mpInputStream->SeekRel( 2 ); // Skip Reserved 2 bytes (it must be ignored)
@@ -833,12 +823,13 @@ namespace emfio
mpInputStream->ReadInt16( nBitmapType ).ReadInt16( nWidth ).ReadInt16( nHeight ).ReadInt16( nBytesPerScan ).ReadUChar( nPlanes ).ReadUChar( nBitCount );
SAL_INFO("emfio", "\t\t Bitmap type:" << nBitmapType << " Width:" << nWidth << " Height:" << nHeight << " WidthBytes:" << nBytesPerScan << " Planes: " << static_cast< sal_uInt16 >( nPlanes ) << " BitCount: " << static_cast< sal_uInt16 >( nBitCount ) );
- if ( bNoSourceBitmap )
+ if ( bNoSourceBitmap || ( nBitCount == 4 ) || ( nBitCount == 8 ) || nPlanes != 1 )
{
- SAL_WARN("emfio", "\t\t TODO The unsupported Bitmap record (without embedded source Bitmap). Please fill a bug.");
+ SAL_WARN("emfio", "\t\t TODO The unsupported Bitmap record. Please fill a bug.");
break;
}
- bool bOk = nWidth && nHeight && nBytesPerScan > 0 && nPlanes == 1 && nBitCount == 1;
+ const vcl::PixelFormat ePixelFormat = vcl::bitDepthToPixelFormat( nBitCount );
+ bool bOk = nWidth && nHeight && nBytesPerScan > 0 && nPlanes == 1 && ePixelFormat != vcl::PixelFormat::INVALID;
if (bOk)
{
// must be enough data to fulfil the request
@@ -851,25 +842,10 @@ namespace emfio
}
if (bOk)
{
- vcl::bitmap::RawBitmap aBmp( Size( nWidth, nHeight ), 24 );
- for (sal_uInt16 y = 0; y < nHeight && mpInputStream->good(); ++y)
- {
- sal_uInt16 x = 0;
- for (sal_uInt16 scan = 0; scan < nBytesPerScan; scan++ )
- {
- sal_Int8 nEightPixels = 0;
- mpInputStream->ReadSChar( nEightPixels );
- for (sal_Int8 i = 7; i >= 0; i-- )
- {
- if ( x < nWidth )
- {
- aBmp.SetPixel( y, x, ((nEightPixels>>i)&1) ? COL_BLACK : COL_WHITE );
- }
- x++;
- }
- }
- }
- BitmapEx aBitmap = vcl::bitmap::CreateFromData(std::move(aBmp));
+ std::unique_ptr< sal_uInt8[] > pData;
+ pData.reset( new sal_uInt8[ nHeight * nBytesPerScan ] );
+ mpInputStream->ReadBytes( pData.get(), nHeight * nBytesPerScan );
+ BitmapEx aBitmap = vcl::bitmap::CreateFromData( pData.get(), nWidth, nHeight, nBytesPerScan, ePixelFormat, true );
if ( nSye && nSxe &&
( nXSrc + nSxe <= nWidth ) &&
( nYSrc + nSye <= nHeight ) )
@@ -885,7 +861,6 @@ namespace emfio
case W_META_DIBBITBLT:
case W_META_DIBSTRETCHBLT:
- case W_META_STRETCHBLT:
case W_META_STRETCHDIB:
{
sal_uInt32 nRasterOperation = 0;
@@ -902,56 +877,49 @@ namespace emfio
// nSrcHeight and nSrcWidth is the number of pixels that has to been used
// If they are set to zero, it is as indicator not to scale the bitmap later
if( nFunc == W_META_DIBSTRETCHBLT ||
- nFunc == W_META_STRETCHBLT ||
nFunc == W_META_STRETCHDIB )
mpInputStream->ReadInt16( nSrcHeight ).ReadInt16( nSrcWidth );
// nYSrc and nXSrc is the offset of the first pixel
mpInputStream->ReadInt16( nYSrc ).ReadInt16( nXSrc );
- // TODO Add META_STRETCHBLT support, which is defined by Bitmap16 Object
- if( nFunc == W_META_DIBBITBLT ||
- nFunc == W_META_DIBSTRETCHBLT ||
- nFunc == W_META_STRETCHDIB )
- {
- if ( bNoSourceBitmap )
- mpInputStream->SeekRel( 2 ); // Skip Reserved 2 bytes (it must be ignored)
+ if ( bNoSourceBitmap )
+ mpInputStream->SeekRel( 2 ); // Skip Reserved 2 bytes (it must be ignored)
- Size aDestSize( ReadYXExt() );
- if ( aDestSize.Width() && aDestSize.Height() ) // #92623# do not try to read buggy bitmaps
+ Size aDestSize( ReadYXExt() );
+ if ( aDestSize.Width() && aDestSize.Height() ) // #92623# do not try to read buggy bitmaps
+ {
+ tools::Rectangle aDestRect( ReadYX(), aDestSize );
+ if ( !bNoSourceBitmap )
{
- tools::Rectangle aDestRect( ReadYX(), aDestSize );
- if ( !bNoSourceBitmap )
- {
- // tdf#142625 Read the DIBHeader and check if bitmap is supported
- // If bitmap is not supported don't run ReadDIB, as it will interrupt image processing
- const auto nOldPos(mpInputStream->Tell());
- sal_uInt32 nHeaderSize;
- sal_uInt16 nBitCount;
- mpInputStream->ReadUInt32( nHeaderSize );
- if ( nHeaderSize == 0xC ) // BitmapCoreHeader
- mpInputStream->SeekRel( 6 ); // skip Width (16), Height (16), Planes (16)
- else
- mpInputStream->SeekRel( 10 ); // skip Width (32), Height (32), Planes (16)
- mpInputStream->ReadUInt16( nBitCount );
- if ( nBitCount == 0 ) // TODO Undefined BitCount (JPEG/PNG), which are not supported
- break;
- mpInputStream->Seek(nOldPos);
-
- if ( !ReadDIB( aBmp, *mpInputStream, false ) )
- SAL_WARN( "emfio", "\tTODO Read DIB failed. Interrupting processing whole image. Please report bug report." );
- }
- // test if it is sensible to crop
- if ( nSrcHeight && nSrcWidth &&
- ( nXSrc + nSrcWidth <= aBmp.GetSizePixel().Width() ) &&
- ( nYSrc + nSrcHeight <= aBmp.GetSizePixel().Height() ) )
- {
- tools::Rectangle aCropRect( Point( nXSrc, nYSrc ), Size( nSrcWidth, nSrcHeight ) );
- aBmp.Crop( aCropRect );
- }
+ // tdf#142625 Read the DIBHeader and check if bitmap is supported
+ // If bitmap is not supported don't run ReadDIB, as it will interrupt image processing
+ const auto nOldPos(mpInputStream->Tell());
+ sal_uInt32 nHeaderSize;
+ sal_uInt16 nBitCount;
+ mpInputStream->ReadUInt32( nHeaderSize );
+ if ( nHeaderSize == 0xC ) // BitmapCoreHeader
+ mpInputStream->SeekRel( 6 ); // skip Width (16), Height (16), Planes (16)
+ else
+ mpInputStream->SeekRel( 10 ); // skip Width (32), Height (32), Planes (16)
+ mpInputStream->ReadUInt16( nBitCount );
+ if ( nBitCount == 0 ) // TODO Undefined BitCount (JPEG/PNG), which are not supported
+ break;
+ mpInputStream->Seek(nOldPos);
- maBmpSaveList.emplace_back(new BSaveStruct(aBmp, aDestRect, nRasterOperation));
+ if ( !ReadDIB( aBmp, *mpInputStream, false ) )
+ SAL_WARN( "emfio", "\tTODO Read DIB failed. Interrupting processing whole image. Please report bug report." );
}
+ // test if it is sensible to crop
+ if ( nSrcHeight && nSrcWidth &&
+ ( nXSrc + nSrcWidth <= aBmp.GetSizePixel().Width() ) &&
+ ( nYSrc + nSrcHeight <= aBmp.GetSizePixel().Height() ) )
+ {
+ tools::Rectangle aCropRect( Point( nXSrc, nYSrc ), Size( nSrcWidth, nSrcHeight ) );
+ aBmp.Crop( aCropRect );
+ }
+
+ maBmpSaveList.emplace_back(new BSaveStruct(aBmp, aDestRect, nRasterOperation));
}
}
break;
diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx
index fa7a43bc99a6..8b1a81413d01 100644
--- a/include/vcl/BitmapTools.hxx
+++ b/include/vcl/BitmapTools.hxx
@@ -46,7 +46,7 @@ void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx,
@param nStride
The number of bytes in a scanline, must be >= (width * bitcount / 8)
*/
-BitmapEx VCL_DLLPUBLIC CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, vcl::PixelFormat ePixelFormat);
+BitmapEx VCL_DLLPUBLIC CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, vcl::PixelFormat ePixelFormat, bool bReversColors = false);
BitmapEx VCL_DLLPUBLIC CreateFromData( RawBitmap && data );
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx
index 32204a4a2bb1..0ebbdae59521 100644
--- a/vcl/source/bitmap/BitmapTools.cxx
+++ b/vcl/source/bitmap/BitmapTools.cxx
@@ -125,8 +125,10 @@ void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx,
The block of data to copy
@param nStride
The number of bytes in a scanline, must >= (width * nBitCount / 8)
+ @param bReversColors
+ In case the indianess of pData is wrong, you could reverse colors
*/
-BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, vcl::PixelFormat ePixelFormat)
+BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, vcl::PixelFormat ePixelFormat, bool bReversColors )
{
auto nBitCount = sal_uInt16(ePixelFormat);
@@ -150,11 +152,12 @@ BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHe
{
for( tools::Long y = 0; y < nHeight; ++y )
{
+ sal_uInt8 const *p = pData + y * nStride / 8;
Scanline pScanline = pWrite->GetScanline(y);
for (tools::Long x = 0; x < nWidth; ++x)
{
- sal_uInt8 const *p = pData + y * nStride / 8;
- int bitIndex = (y * nStride) % 8;
+ int bitIndex = (y * nStride + x) % 8;
+
pWrite->SetPixelOnData(pScanline, x, BitmapColor((*p >> bitIndex) & 1));
}
}
@@ -167,7 +170,11 @@ BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHe
Scanline pScanline = pWrite->GetScanline(y);
for (tools::Long x = 0; x < nWidth; ++x)
{
- BitmapColor col(p[0], p[1], p[2]);
+ BitmapColor col;
+ if ( bReversColors )
+ col = BitmapColor( p[2], p[1], p[0] );
+ else
+ col = BitmapColor( p[0], p[1], p[2] );
pWrite->SetPixelOnData(pScanline, x, col);
p += nBitCount/8;
}