Fix loading of RLE bitmaps in wxBMPHandler
- Fix handling of delta encoding that change vertical position - Fix handling of end-of-line encodings that are given mid-line - Removed unnecessary computation for linepos Add regression tests for the bitmaps using RLE and loading which previously didn't work correctly. Closes https://github.com/wxWidgets/wxWidgets/pull/2590 Closes #19318.
This commit is contained in:
committed by
Vadim Zeitlin
parent
94f10eba4e
commit
0985996d01
@@ -146,6 +146,9 @@ set(TEST_GUI_DATA
|
|||||||
horse.xpm
|
horse.xpm
|
||||||
image/8bpp-colorsused-large.bmp
|
image/8bpp-colorsused-large.bmp
|
||||||
image/8bpp-colorsused-negative.bmp
|
image/8bpp-colorsused-negative.bmp
|
||||||
|
image/rle4-delta-320x240.bmp
|
||||||
|
image/rle8-delta-320x240-expected.bmp
|
||||||
|
image/rle8-delta-320x240.bmp
|
||||||
image/horse_grey.bmp
|
image/horse_grey.bmp
|
||||||
image/horse_grey_flipped.bmp
|
image/horse_grey_flipped.bmp
|
||||||
image/horse_rle4.bmp
|
image/horse_rle4.bmp
|
||||||
|
|||||||
@@ -772,11 +772,15 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
|
|
||||||
if ( first == 0 )
|
if ( first == 0 )
|
||||||
{
|
{
|
||||||
|
// This is an escape sequence with special meaning.
|
||||||
if ( aByte == 0 )
|
if ( aByte == 0 )
|
||||||
{
|
{
|
||||||
// end of scanline marker
|
// end of scanline marker
|
||||||
|
// This is ignored if the end-of-line was
|
||||||
|
// implicitly assumed when column==width,
|
||||||
|
// in which case column is now 0.
|
||||||
|
if (column != 0)
|
||||||
column = width;
|
column = width;
|
||||||
row--;
|
|
||||||
}
|
}
|
||||||
else if ( aByte == 1 )
|
else if ( aByte == 1 )
|
||||||
{
|
{
|
||||||
@@ -787,18 +791,23 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
else if ( aByte == 2 )
|
else if ( aByte == 2 )
|
||||||
{
|
{
|
||||||
// delta marker, move in image
|
// delta marker, move in image
|
||||||
|
|
||||||
|
// process column offset
|
||||||
aByte = stream.GetC();
|
aByte = stream.GetC();
|
||||||
if ( !stream.IsOk() )
|
if ( !stream.IsOk() )
|
||||||
return false;
|
return false;
|
||||||
column += aByte;
|
column += aByte;
|
||||||
linepos = column * bpp / 4;
|
|
||||||
|
// process row offset
|
||||||
aByte = stream.GetC();
|
aByte = stream.GetC();
|
||||||
if ( !stream.IsOk() )
|
if ( !stream.IsOk() )
|
||||||
return false;
|
return false;
|
||||||
row += aByte; // upside down
|
row += aByte;
|
||||||
|
line = isUpsideDown ? height - 1 - row : row;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// absolute mode (pixels not runs)
|
||||||
int absolute = aByte;
|
int absolute = aByte;
|
||||||
wxUint8 nibble[2] ;
|
wxUint8 nibble[2] ;
|
||||||
int readBytes = 0 ;
|
int readBytes = 0 ;
|
||||||
@@ -817,8 +826,6 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
ptr[poffset + 1] = cmap[nibble[k%2]].g;
|
ptr[poffset + 1] = cmap[nibble[k%2]].g;
|
||||||
ptr[poffset + 2] = cmap[nibble[k%2]].b;
|
ptr[poffset + 2] = cmap[nibble[k%2]].b;
|
||||||
column++;
|
column++;
|
||||||
if ( k % 2 )
|
|
||||||
linepos++;
|
|
||||||
}
|
}
|
||||||
if ( readBytes & 0x01 )
|
if ( readBytes & 0x01 )
|
||||||
{
|
{
|
||||||
@@ -840,8 +847,6 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
ptr[poffset + 1] = cmap[nibble[l%2]].g;
|
ptr[poffset + 1] = cmap[nibble[l%2]].g;
|
||||||
ptr[poffset + 2] = cmap[nibble[l%2]].b;
|
ptr[poffset + 2] = cmap[nibble[l%2]].b;
|
||||||
column++;
|
column++;
|
||||||
if ( l % 2 )
|
|
||||||
linepos++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -874,8 +879,11 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
if ( aByte == 0 )
|
if ( aByte == 0 )
|
||||||
{
|
{
|
||||||
// end of scanline marker
|
// end of scanline marker
|
||||||
|
// This is ignored if the end-of-line was
|
||||||
|
// implicitly assumed when column==width,
|
||||||
|
// in which case column is now 0.
|
||||||
|
if (column != 0)
|
||||||
column = width;
|
column = width;
|
||||||
row--;
|
|
||||||
}
|
}
|
||||||
else if ( aByte == 1 )
|
else if ( aByte == 1 )
|
||||||
{
|
{
|
||||||
@@ -886,22 +894,26 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
else if ( aByte == 2 )
|
else if ( aByte == 2 )
|
||||||
{
|
{
|
||||||
// delta marker, move in image
|
// delta marker, move in image
|
||||||
|
|
||||||
|
// process column offset
|
||||||
aByte = stream.GetC();
|
aByte = stream.GetC();
|
||||||
if ( !stream.IsOk() )
|
if ( !stream.IsOk() )
|
||||||
return false;
|
return false;
|
||||||
column += aByte;
|
column += aByte;
|
||||||
linepos = column * bpp / 8;
|
|
||||||
|
// process row offset
|
||||||
aByte = stream.GetC();
|
aByte = stream.GetC();
|
||||||
if ( !stream.IsOk() )
|
if ( !stream.IsOk() )
|
||||||
return false;
|
return false;
|
||||||
row -= aByte;
|
row += aByte;
|
||||||
|
line = isUpsideDown ? height - 1 - row : row;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// absolute mode (pixels not runs)
|
||||||
int absolute = aByte;
|
int absolute = aByte;
|
||||||
for (int k = 0; k < absolute; k++)
|
for (int k = 0; k < absolute; k++)
|
||||||
{
|
{
|
||||||
linepos++;
|
|
||||||
aByte = stream.GetC();
|
aByte = stream.GetC();
|
||||||
if ( !stream.IsOk() )
|
if ( !stream.IsOk() )
|
||||||
return false;
|
return false;
|
||||||
@@ -920,13 +932,13 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// encoded mode (repeat aByte first times)
|
||||||
for ( int l = 0; l < first && column < width; l++ )
|
for ( int l = 0; l < first && column < width; l++ )
|
||||||
{
|
{
|
||||||
ptr[poffset ] = cmap[aByte].r;
|
ptr[poffset ] = cmap[aByte].r;
|
||||||
ptr[poffset + 1] = cmap[aByte].g;
|
ptr[poffset + 1] = cmap[aByte].g;
|
||||||
ptr[poffset + 2] = cmap[aByte].b;
|
ptr[poffset + 2] = cmap[aByte].b;
|
||||||
column++;
|
column++;
|
||||||
linepos++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -994,7 +1006,7 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
|
|||||||
column++;
|
column++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ( (linepos < linesize) && (comp != 1) && (comp != 2) )
|
while ( (linepos < linesize) && (comp != BI_RLE8) && (comp != BI_RLE4) )
|
||||||
{
|
{
|
||||||
++linepos;
|
++linepos;
|
||||||
if ( !stream.ReadAll(&aByte, 1) )
|
if ( !stream.ReadAll(&aByte, 1) )
|
||||||
|
|||||||
@@ -565,7 +565,7 @@ data:
|
|||||||
|
|
||||||
data-images:
|
data-images:
|
||||||
@mkdir -p image
|
@mkdir -p image
|
||||||
@for f in 8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png; do \
|
@for f in 8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png; do \
|
||||||
if test ! -f image/$$f -a ! -d image/$$f ; \
|
if test ! -f image/$$f -a ! -d image/$$f ; \
|
||||||
then x=yep ; \
|
then x=yep ; \
|
||||||
else x=`find $(srcdir)/image/$$f -newer image/$$f -print` ; \
|
else x=`find $(srcdir)/image/$$f -newer image/$$f -print` ; \
|
||||||
|
|||||||
@@ -1355,6 +1355,11 @@ void ImageTestCase::BMPFlippingAndRLECompression()
|
|||||||
CompareBMPImage("image/horse_rle8.bmp", "image/horse_rle8_flipped.bmp");
|
CompareBMPImage("image/horse_rle8.bmp", "image/horse_rle8_flipped.bmp");
|
||||||
|
|
||||||
CompareBMPImage("image/horse_rle4.bmp", "image/horse_rle4_flipped.bmp");
|
CompareBMPImage("image/horse_rle4.bmp", "image/horse_rle4_flipped.bmp");
|
||||||
|
|
||||||
|
CompareBMPImage("image/rle8-delta-320x240.bmp",
|
||||||
|
"image/rle8-delta-320x240-expected.bmp");
|
||||||
|
CompareBMPImage("image/rle4-delta-320x240.bmp",
|
||||||
|
"image/rle8-delta-320x240-expected.bmp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
tests/image/rle4-delta-320x240.bmp
Normal file
BIN
tests/image/rle4-delta-320x240.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
tests/image/rle8-delta-320x240-expected.bmp
Normal file
BIN
tests/image/rle8-delta-320x240-expected.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
tests/image/rle8-delta-320x240.bmp
Normal file
BIN
tests/image/rle8-delta-320x240.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -555,7 +555,7 @@ data:
|
|||||||
|
|
||||||
data-images:
|
data-images:
|
||||||
if not exist image mkdir image
|
if not exist image mkdir image
|
||||||
for %%f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png) do if not exist image\%%f copy .\image\%%f image
|
for %%f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png) do if not exist image\%%f copy .\image\%%f image
|
||||||
|
|
||||||
fr:
|
fr:
|
||||||
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
||||||
|
|||||||
@@ -989,7 +989,7 @@ data:
|
|||||||
|
|
||||||
data-images:
|
data-images:
|
||||||
if not exist image mkdir image
|
if not exist image mkdir image
|
||||||
for %f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png) do if not exist image\%f copy .\image\%f image
|
for %f in (8bpp-colorsused-large.bmp 8bpp-colorsused-negative.bmp rle4-delta-320x240.bmp rle8-delta-320x240.bmp rle8-delta-320x240-expected.bmp horse_grey.bmp horse_grey_flipped.bmp horse_rle4.bmp horse_rle4_flipped.bmp horse_rle8.bmp horse_rle8_flipped.bmp horse_bicubic_50x50.png horse_bicubic_100x100.png horse_bicubic_150x150.png horse_bicubic_300x300.png horse_bilinear_50x50.png horse_bilinear_100x100.png horse_bilinear_150x150.png horse_bilinear_300x300.png horse_box_average_50x50.png horse_box_average_100x100.png horse_box_average_150x150.png horse_box_average_300x300.png cross_bicubic_256x256.png cross_bilinear_256x256.png cross_box_average_256x256.png cross_nearest_neighb_256x256.png paste_input_background.png paste_input_black.png paste_input_overlay_transparent_border_opaque_square.png paste_input_overlay_transparent_border_semitransparent_circle.png paste_input_overlay_transparent_border_semitransparent_square.png paste_result_background_plus_circle_plus_square.png paste_result_background_plus_overlay_transparent_border_opaque_square.png paste_result_background_plus_overlay_transparent_border_semitransparent_square.png paste_result_no_background_square_over_circle.png wx.png wx.ico toucan.png toucan_hue_0.538.png toucan_sat_-0.41.png toucan_bright_-0.259.png toucan_hsv_0.538_-0.41_-0.259.png toucan_light_46.png toucan_dis_240.png toucan_grey.png toucan_mono_255_255_255.png) do if not exist image\%f copy .\image\%f image
|
||||||
|
|
||||||
fr:
|
fr:
|
||||||
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
if not exist $(OBJS)\intl\fr mkdir $(OBJS)\intl\fr
|
||||||
|
|||||||
@@ -351,6 +351,9 @@
|
|||||||
<files>
|
<files>
|
||||||
8bpp-colorsused-large.bmp
|
8bpp-colorsused-large.bmp
|
||||||
8bpp-colorsused-negative.bmp
|
8bpp-colorsused-negative.bmp
|
||||||
|
rle4-delta-320x240.bmp
|
||||||
|
rle8-delta-320x240.bmp
|
||||||
|
rle8-delta-320x240-expected.bmp
|
||||||
|
|
||||||
horse_grey.bmp horse_grey_flipped.bmp
|
horse_grey.bmp horse_grey_flipped.bmp
|
||||||
horse_rle4.bmp horse_rle4_flipped.bmp
|
horse_rle4.bmp horse_rle4_flipped.bmp
|
||||||
|
|||||||
Reference in New Issue
Block a user