Skip to content

Commit ac5a795

Browse files
SyntevoAlexniraj-modi
authored andcommitted
Bug 576334 - Image is loaded with wrong colors from 32-bit BMP
Change-Id: I91fe91c6f29f949bcac349c3cc2c5925b0d7b03e Signed-off-by: Alexandr Miloslavskiy <[email protected]> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/185958 Tested-by: Platform Bot <[email protected]> Tested-by: Niraj Modi <[email protected]> Reviewed-by: Niraj Modi <[email protected]>
1 parent 763434c commit ac5a795

File tree

3 files changed

+70
-8
lines changed

3 files changed

+70
-8
lines changed

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinBMPFileFormat.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
public final class WinBMPFileFormat extends FileFormat {
2222
static final int BMPFileHeaderSize = 14;
2323
static final int BMPHeaderFixedSize = 40;
24+
25+
static final int BI_RGB = 0;
26+
static final int BI_RLE8 = 1;
27+
static final int BI_RLE4 = 2;
28+
static final int BI_BITFIELDS = 3;
29+
2430
int importantColors;
2531
Point pelsPerMeter = new Point(0, 0);
2632

@@ -31,10 +37,10 @@ public final class WinBMPFileFormat extends FileFormat {
3137
* Answer the size of the compressed data.
3238
*/
3339
int compress(int comp, byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) {
34-
if (comp == 1) { // BMP_RLE8_COMPRESSION
40+
if (comp == BI_RLE8) {
3541
return compressRLE8Data(src, srcOffset, numBytes, dest, last);
3642
}
37-
if (comp == 2) { // BMP_RLE4_COMPRESSION
43+
if (comp == BI_RLE4) {
3844
return compressRLE4Data(src, srcOffset, numBytes, dest, last);
3945
}
4046
SWT.error(SWT.ERROR_INVALID_IMAGE);
@@ -271,12 +277,12 @@ void convertPixelsToBGR(ImageData image, byte[] dest) {
271277
}
272278
}
273279
void decompressData(byte[] src, byte[] dest, int stride, int cmp) {
274-
if (cmp == 1) { // BMP_RLE8_COMPRESSION
280+
if (cmp == BI_RLE8) {
275281
if (decompressRLE8Data(src, src.length, stride, dest, dest.length) <= 0)
276282
SWT.error(SWT.ERROR_INVALID_IMAGE);
277283
return;
278284
}
279-
if (cmp == 2) { // BMP_RLE4_COMPRESSION
285+
if (cmp == BI_RLE4) {
280286
if (decompressRLE4Data(src, src.length, stride, dest, dest.length) <= 0)
281287
SWT.error(SWT.ERROR_INVALID_IMAGE);
282288
return;
@@ -452,7 +458,7 @@ byte[] loadData(byte[] infoHeader, int stride) {
452458
int dataSize = height * stride;
453459
byte[] data = new byte[dataSize];
454460
int cmp = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24);
455-
if (cmp == 0 || cmp == 3) { // BMP_NO_COMPRESSION
461+
if (cmp == BI_RGB || cmp == BI_BITFIELDS) {
456462
try {
457463
if (inputStream.read(data) != dataSize)
458464
SWT.error(SWT.ERROR_INVALID_IMAGE);
@@ -556,7 +562,7 @@ PaletteData loadPalette(byte[] infoHeader) {
556562
return paletteFromBytes(buf, numColors);
557563
}
558564
if (depth == 16) {
559-
if (this.compression == 3) {
565+
if (this.compression == BI_BITFIELDS) {
560566
try {
561567
return new PaletteData(inputStream.readInt(), inputStream.readInt(), inputStream.readInt());
562568
} catch (IOException e) {
@@ -566,9 +572,18 @@ PaletteData loadPalette(byte[] infoHeader) {
566572
return new PaletteData(0x7C00, 0x3E0, 0x1F);
567573
}
568574
if (depth == 24) return new PaletteData(0xFF, 0xFF00, 0xFF0000);
569-
if (this.compression == 3) {
575+
if (this.compression == BI_BITFIELDS) {
570576
try {
571-
return new PaletteData(inputStream.readInt(), inputStream.readInt(), inputStream.readInt());
577+
/*
578+
* ImageData is expected to be in big-endian format when
579+
* (bpp != 16); see 'ImageData.getByteOrder()'. At the same
580+
* time, 'inputStream' is a 'LEDataInputStream', that is,
581+
* low-endian. Therefore, masks need to be converted.
582+
*/
583+
final int maskR = Integer.reverseBytes(inputStream.readInt());
584+
final int maskG = Integer.reverseBytes(inputStream.readInt());
585+
final int maskB = Integer.reverseBytes(inputStream.readInt());
586+
return new PaletteData(maskR, maskG, maskB);
572587
} catch (IOException e) {
573588
SWT.error(SWT.ERROR_IO, e);
574589
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2021 Syntevo and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Syntevo - initial API and implementation
13+
*******************************************************************************/
14+
15+
package org.eclipse.swt.tests.manual;
16+
17+
import org.eclipse.swt.graphics.*;
18+
import org.eclipse.swt.layout.GridLayout;
19+
import org.eclipse.swt.widgets.*;
20+
21+
import java.io.InputStream;
22+
23+
public class Bug576334_32bpp_BMP_Colors {
24+
public static void main (String[] args) {
25+
final Display display = new Display ();
26+
final Shell shell = new Shell (display);
27+
shell.setLayout (new GridLayout ());
28+
29+
Label hint = new Label (shell, 0);
30+
hint.setText ("The image below shall be orange; not green");
31+
32+
InputStream imageStream = Bug576334_32bpp_BMP_Colors.class.getResourceAsStream ("/Bug576334_32bpp_BMP_Colors.bmp");
33+
ImageData imageData = new ImageData (imageStream);
34+
Image image = new Image (display, imageData);
35+
36+
Label imageLabel = new Label (shell, 0);
37+
imageLabel.setImage (image);
38+
39+
shell.pack ();
40+
shell.open ();
41+
while (!shell.isDisposed ()) {
42+
if (!display.readAndDispatch ())
43+
display.sleep ();
44+
}
45+
display.dispose ();
46+
}
47+
}
Binary file not shown.

0 commit comments

Comments
 (0)