Skip to content

Commit cdea7a4

Browse files
committed
Improve and extend tests for Image#getImageData()
- makes multiple test methods with more comprehensive names out of a combined single one - adds test method for additional use case - adds win32-specific tests methods for specifics in Windows image handling
1 parent f0e13ed commit cdea7a4

File tree

4 files changed

+132
-72
lines changed

4 files changed

+132
-72
lines changed

tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/graphics/ImageWin32Tests.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.swt.graphics;
1515

1616

17+
import static org.eclipse.swt.tests.win32.SwtWin32TestUtil.assertImageDataEqualsIgnoringAlphaInData;
1718
import static org.junit.jupiter.api.Assertions.assertEquals;
1819
import static org.junit.jupiter.api.Assertions.assertNotEquals;
1920

@@ -174,4 +175,42 @@ public void testDisposeDrawnImageBeforeRequestingTargetForOtherZoom() {
174175
}
175176
}
176177

178+
// On Windows, the first used Image constructor creates a DDB, while the second
179+
// transforms it into a DIB, still pixel RGB and alpha values should be the same.
180+
@Test
181+
public void test_getImageData_fromImageForImageDataFromImage() {
182+
int width = 10;
183+
int height = 10;
184+
Color color = new Color(0, 0xff, 0);
185+
Image image = new Image(display, width, height);
186+
fillImage(image, color);
187+
ImageData imageData = image.getImageData();
188+
ImageData recreatedImageData = new Image(display, imageData).getImageData();
189+
assertImageDataEqualsIgnoringAlphaInData(imageData, recreatedImageData);
190+
image.dispose();
191+
}
192+
193+
// On Windows, the first used Image constructor creates a DDB, while the second
194+
// transforms it into a DIB, still pixel RGB and alpha values should be the same.
195+
@Test
196+
public void test_getImageData_fromCopiedImage() {
197+
int width = 10;
198+
int height = 10;
199+
Color color = new Color(0, 0xff, 0);
200+
Image image = new Image(display, width, height);
201+
fillImage(image, color);
202+
ImageData imageData = image.getImageData();
203+
ImageData copiedImageData = new Image(display, image, SWT.IMAGE_COPY).getImageData();
204+
assertImageDataEqualsIgnoringAlphaInData(imageData, copiedImageData);
205+
image.dispose();
206+
}
207+
208+
private static void fillImage(Image image, Color fillColor) {
209+
GC gc = new GC(image);
210+
gc.setBackground(fillColor);
211+
gc.setForeground(fillColor);
212+
gc.fillRectangle(image.getBounds());
213+
gc.dispose();
214+
}
215+
177216
}

tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/SwtWin32TestUtil.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.tests.win32;
1515

16+
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
import static org.junit.jupiter.api.Assertions.assertNotNull;
18+
1619
import java.util.function.BooleanSupplier;
1720

21+
import org.eclipse.swt.graphics.ImageData;
1822
import org.eclipse.swt.widgets.Display;
1923

2024
public class SwtWin32TestUtil {
@@ -41,4 +45,45 @@ public static void processEvents(Display display, int timeoutMs, BooleanSupplier
4145
}
4246
}
4347
}
48+
49+
/**
50+
* Asserts that both given ImageData are equal, i.e. that:
51+
* <ul>
52+
* <li>depths are equal (considering 24/32 bit as equals since alpha data is stored separately)</li>
53+
* <li>width and height are equal</li>
54+
* <li>all pixel RGB values are equal</li>
55+
* <li>all pixel alpha values in the alphaData are equal</li>
56+
* </ul>
57+
* In case any of these properties differ, the test will fail.
58+
*
59+
* @param expected the expected ImageData
60+
* @param actual the actual ImageData
61+
*/
62+
// This method is necessary because ImageData has no custom equals method and the default one isn't sufficient.
63+
public static void assertImageDataEqualsIgnoringAlphaInData(final ImageData expected, final ImageData actual) {
64+
assertNotNull(expected, "expected data must not be null");
65+
assertNotNull(actual, "actual data must not be null");
66+
if (expected == actual) {
67+
return;
68+
}
69+
assertEquals(expected.height, actual.height, "height of expected image is different from actual image");
70+
// Alpha values are taken from alpha data, so ignore whether data depth is 24 or 32 bits
71+
int expectedNormalizedDepth = expected.depth == 32 ? 24 : expected.depth;
72+
int actualNormalizedDepth = expected.depth == 32 ? 24 : expected.depth;
73+
assertEquals(expectedNormalizedDepth, actualNormalizedDepth, "depth of image data to compare must be equal");
74+
assertEquals(expected.width, actual.width, "width of expected image is different from actual image");
75+
76+
for (int y = 0; y < expected.height; y++) {
77+
for (int x = 0; x < expected.width; x++) {
78+
// FIXME win32: dragged ALPHA=FF, dropped ALPHA=00, but other transparencyType
79+
// => alpha stored in ImageData.alphaData
80+
String expectedPixel = String.format("0x%08X", expected.getPixel(x, y) >> (expected.depth == 32 ? 8 : 0));
81+
String actualPixel = String.format("0x%08X", actual.getPixel(x, y) >> (actual.depth == 32 ? 8 : 0));
82+
assertEquals(expectedPixel, actualPixel, "actual pixel at x=" + x + " y=" + y + " is different from expected pixel");
83+
int expectedAlpha = expected.getAlpha(x, y);
84+
int actualAlpha = actual.getAlpha(x, y);
85+
assertEquals(expectedAlpha, actualAlpha, "actual pixel alpha at x=" + x + " y=" + y + " is different from expected pixel");
86+
}
87+
}
88+
}
4489
}

tests/org.eclipse.swt.tests.win32/JUnit Tests/org/eclipse/swt/tests/win32/Test_org_eclipse_swt_dnd_DND.java

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.tests.win32;
1515

16+
import static org.eclipse.swt.tests.win32.SwtWin32TestUtil.assertImageDataEqualsIgnoringAlphaInData;
1617
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
1718
import static org.junit.jupiter.api.Assertions.assertEquals;
1819
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -144,7 +145,7 @@ public void testImageTransfer_fromImage() throws InterruptedException {
144145
try {
145146
final ImageData drag = image.getImageData();
146147
final ImageData drop = testTransferRoundtrip(ImageTransfer.getInstance(), drag);
147-
assertImageDataEqualsIgoringAlphaInData(drag, drop);
148+
assertImageDataEqualsIgnoringAlphaInData(drag, drop);
148149
} finally {
149150
image.dispose();
150151
}
@@ -159,7 +160,7 @@ public void testImageTransfer_fromCopiedImage() throws InterruptedException {
159160
try {
160161
final ImageData drag = new Image(shell.getDisplay(), image, SWT.IMAGE_COPY).getImageData();
161162
final ImageData drop = testTransferRoundtrip(ImageTransfer.getInstance(), drag);
162-
assertImageDataEqualsIgoringAlphaInData(drag, drop);
163+
assertImageDataEqualsIgnoringAlphaInData(drag, drop);
163164
} finally {
164165
image.dispose();
165166
}
@@ -176,7 +177,7 @@ public void testImageTransfer_fromImageData() throws InterruptedException {
176177
}
177178
final ImageData drag = imageData;
178179
final ImageData drop = testTransferRoundtrip(ImageTransfer.getInstance(), drag);
179-
assertImageDataEqualsIgoringAlphaInData(drag, drop);
180+
assertImageDataEqualsIgnoringAlphaInData(drag, drop);
180181
}
181182

182183
/**
@@ -190,7 +191,7 @@ public void testImageTransfer_fromImageDataFromImage() throws InterruptedExcepti
190191
try {
191192
final ImageData drag = imageFromImageData.getImageData();
192193
final ImageData drop = testTransferRoundtrip(ImageTransfer.getInstance(), drag);
193-
assertImageDataEqualsIgoringAlphaInData(drag, drop);
194+
assertImageDataEqualsIgnoringAlphaInData(drag, drop);
194195
} finally {
195196
imageFromImageData.dispose();
196197
}
@@ -252,47 +253,6 @@ private Image createTestImage() {
252253
return null;
253254
}
254255

255-
/**
256-
* Asserts that both given ImageData are equal, i.e. that:
257-
* <ul>
258-
* <li>depths are equal (considering 24/32 bit as equals since alpha data is stored separately)</li>
259-
* <li>width and height are equal</li>
260-
* <li>all pixel RGB values are equal</li>
261-
* <li>all pixel alpha values in the alphaData are equal</li>
262-
* </ul>
263-
* In case any of these properties differ, the test will fail.
264-
*
265-
* @param expected the expected ImageData
266-
* @param actual the actual ImageData
267-
*/
268-
// This method is necessary because ImageData has no custom equals method and the default one isn't sufficient.
269-
private void assertImageDataEqualsIgoringAlphaInData(final ImageData expected, final ImageData actual) {
270-
assertNotNull(expected, "expected data must not be null");
271-
assertNotNull(actual, "actual data must not be null");
272-
if (expected == actual) {
273-
return;
274-
}
275-
assertEquals(expected.height, actual.height, "height of expected image is different from actual image");
276-
// Alpha values are taken from alpha data, so ignore whether data depth is 24 or 32 bits
277-
int expectedNormalizedDepth = expected.depth == 32 ? 24 : expected.depth;
278-
int actualNormalizedDepth = expected.depth == 32 ? 24 : expected.depth;
279-
assertEquals(expectedNormalizedDepth, actualNormalizedDepth, "depth of image data to compare must be equal");
280-
assertEquals(expected.width, actual.width, "width of expected image is different from actual image");
281-
282-
for (int y = 0; y < expected.height; y++) {
283-
for (int x = 0; x < expected.width; x++) {
284-
// FIXME win32: dragged ALPHA=FF, dropped ALPHA=00, but other transparencyType
285-
// => alpha stored in ImageData.alphaData
286-
String expectedPixel = String.format("0x%08X", expected.getPixel(x, y) >> (expected.depth == 32 ? 8 : 0));
287-
String actualPixel = String.format("0x%08X", actual.getPixel(x, y) >> (actual.depth == 32 ? 8 : 0));
288-
assertEquals(expectedPixel, actualPixel, "actual pixel at x=" + x + " y=" + y + " is different from expected pixel");
289-
int expectedAlpha = expected.getAlpha(x, y);
290-
int actualAlpha = actual.getAlpha(x, y);
291-
assertEquals(expectedAlpha, actualAlpha, "actual pixel alpha at x=" + x + " y=" + y + " is different from expected pixel");
292-
}
293-
}
294-
}
295-
296256
/**
297257
* Test transfer implementation by dragging and dropping some data onto ourself.
298258
*

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_Image.java

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -677,13 +677,6 @@ public void test_getImageDataCurrentZoom() {
677677
assertEquals(":d: Size of ImageData returned from Image.getImageDataAtCurrentZoom method doesn't return matches with bounds in Pixel values.", boundsAtCurrentZoom, bounds);
678678
}
679679

680-
@Test
681-
public void test_getImageData() {
682-
getImageData1();
683-
getImageData2(24, new PaletteData(0xff0000, 0xff00, 0xff));
684-
getImageData2(32, new PaletteData(0xff0000, 0xff00, 0xff));
685-
}
686-
687680
@Test
688681
public void test_getImageData_changingImageDataDoesNotAffectImage() {
689682
List<Image> images = List.of( //
@@ -920,11 +913,12 @@ public void test_toString() {
920913
/* custom */
921914
Display display;
922915

923-
/** Test implementation **/
924-
925-
void getImageData1() {
916+
@Test
917+
public void test_getImageData_fromFiles() {
918+
int numFormats = SwtTestUtil.imageFormats.length;
926919
String fileName = SwtTestUtil.imageFilenames[0];
927-
for (String format : SwtTestUtil.imageFormats) {
920+
for (int i=0; i<numFormats; i++) {
921+
String format = SwtTestUtil.imageFormats[i];
928922
try (InputStream stream = SwtTestUtil.class.getResourceAsStream(fileName + "." + format)) {
929923
ImageData data1 = new ImageData(stream);
930924
Image image = new Image(display, data1);
@@ -942,31 +936,53 @@ void getImageData1() {
942936
* Verify Image.getImageData returns pixels with the same RGB value as the
943937
* source image. This test only makes sense with depth of 24 and 32 bits.
944938
*/
945-
void getImageData2(int depth, PaletteData palette) {
939+
@Test
940+
public void test_getImageData_fromImageForCustomImageData() {
946941
int width = 10;
947942
int height = 10;
948943
Color color = new Color(0, 0xff, 0);
949-
RGB colorRGB = color.getRGB();
944+
PaletteData palette = new PaletteData(0xff0000, 0xff00, 0xff);
945+
int[] depths = new int[] { 24, 32 };
946+
for (int depth : depths) {
947+
ImageData imageData = new ImageData(width, height, depth, palette);
948+
Image image = new Image(display, imageData);
949+
fillImage(image, color);
950+
ImageData newData = image.getImageData();
951+
assertAllPixelsHaveColor(newData, color);
952+
image.dispose();
953+
}
954+
}
950955

951-
ImageData imageData = new ImageData(width, height, depth, palette);
952-
Image image = new Image(display, imageData);
956+
@Test
957+
public void test_getImageData_fromImage() {
958+
int width = 10;
959+
int height = 10;
960+
Color color = new Color(0, 0xff, 0);
961+
Image image = new Image(display, width, height);
962+
fillImage(image, color);
963+
ImageData imageData = image.getImageData();
964+
assertAllPixelsHaveColor(imageData, color);
965+
image.dispose();
966+
}
953967

968+
private static void fillImage(Image image, Color fillColor) {
954969
GC gc = new GC(image);
955-
gc.setBackground(color);
956-
gc.setForeground(color);
957-
gc.fillRectangle(0, 0, 10, 10);
958-
959-
ImageData newData = image.getImageData();
960-
PaletteData newPalette = newData.palette;
961-
for (int i = 0; i < width; i++) {
962-
for (int j = 0; j < height; j++) {
963-
int pixel = newData.getPixel(i, j);
970+
gc.setBackground(fillColor);
971+
gc.setForeground(fillColor);
972+
gc.fillRectangle(image.getBounds());
973+
gc.dispose();
974+
}
975+
976+
private static PaletteData assertAllPixelsHaveColor(ImageData imageData, Color expectedColor) {
977+
PaletteData newPalette = imageData.palette;
978+
for (int x = 0; x < imageData.width; x++) {
979+
for (int y = 0; y < imageData.height; y++) {
980+
int pixel = imageData.getPixel(x, y);
964981
RGB rgb = newPalette.getRGB(pixel);
965-
assertTrue("rgb.equals(colorRGB)", rgb.equals(colorRGB));
982+
assertEquals("pixel at x=" + x + " y=" + y + " does not have expected color", expectedColor.getRGB(), rgb);
966983
}
967984
}
968-
gc.dispose();
969-
image.dispose();
985+
return newPalette;
970986
}
971987

972988
RGB getRealRGB(Color color) {

0 commit comments

Comments
 (0)