1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-09-20 06:44:44 +00:00
QB64-PE/tests/compile_tests/utilities/imageassert.bm
2024-06-23 23:01:27 +05:30

194 lines
7.1 KiB
Text

'
' Asserts that a created image, 'originalActualImage', is identical to the provide expected image, 'expectedFileName'
'
' The created image is converted to 32-bit and saved to the results folder.
' We then load the expected image as a 32-bit image, compare file sizes,
' width/height, and each pixel.
'
SUB AssertImage (originalActualImage AS LONG, expectedFileName AS STRING)
DIM actualImage AS LONG
DIM ResultsDir AS STRING, TestPrefix AS STRING
ResultsDir = COMMAND$(1)
TestPrefix = COMMAND$(2)
' Make sure the test result will be seen
_DEST _CONSOLE
' Convert to 32-bit for comparisons
actualImage = _NEWIMAGE(_WIDTH(originalActualImage), _HEIGHT(originalActualImage), 32)
_PUTIMAGE , originalActualImage, actualImage
'First save the result
SaveImage actualImage, ResultsDir + "/" + TestPrefix + "_result.bmp"
'Compare both images, print whether they are identical
DIM expectedImage AS LONG
expectedImage = _LOADIMAGE(expectedFileName, 32)
IF _WIDTH(actualImage) <> _WIDTH(expectedImage) THEN
PRINT "Failure! Image width differs, actual:"; _WIDTH(actualImage); ", Expected:"; _WIDTH(expectedImage)
GOTO freeImages
END IF
IF _HEIGHT(actualImage) <> _HEIGHT(expectedImage) THEN
PRINT "Failure! Image height differs, actual:"; _HEIGHT(actualImage); ", Expected:"; _HEIGHT(expectedImage)
GOTO freeImages
END IF
DIM actual AS _MEM, expected AS _MEM
actual = _MEMIMAGE(actualImage)
expected = _MEMIMAGE(expectedImage)
IF actual.SIZE <> expected.SIZE THEN
PRINT "Failure! Image sizes differ, Actual:"; actual.SIZE; ", Expected:"; expected.SIZE
GOTO freeImages
END IF
DIM w&: w& = _WIDTH(expectedImage)
DIM h&: h& = _HEIGHT(expectedImage)
DIM x&, y&, actualPixel&, expectedPixel&, pixelOffset AS _OFFSET
FOR x& = 0 TO w& - 1
FOR y& = 0 TO h& - 1
pixelOffset = (y& * w& + x&) * 4
actualPixel& = _MEMGET(actual, actual.OFFSET + pixelOffset, LONG)
expectedPixel& = _MEMGET(expected, expected.OFFSET + pixelOffset, LONG)
IF actualPixel& <> expectedPixel& THEN
PRINT "Failure! Image pixels at ("; x&; ","; y&; ") differ, actual: 0x"; HEX$(actualPixel&); ", expected: 0x"; HEX$(expectedPixel&)
GOTO freeImages
END IF
NEXT
NEXT
PRINT "Success, images are identical!"
freeImages:
_MEMFREE actual
_MEMFREE expected
_FREEIMAGE actualImage
END SUB
' From the QB64-PE Wiki: https://qb64phoenix.com/qb64wiki/index.php/SAVEIMAGE
SUB SaveImage (image AS LONG, filename AS STRING)
DIM bytesperpixel&, bpp&
bytesperpixel& = _PIXELSIZE(image&)
IF bytesperpixel& = 0 THEN PRINT "Text modes unsupported!": END
IF bytesperpixel& = 1 THEN bpp& = 8 ELSE bpp& = 24
DIM x&: x& = _WIDTH(image&)
DIM y&: y& = _HEIGHT(image&)
DIM b$: b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + STRING$(16, 0) 'partial BMP header info(???? to be filled later)
DIM c&, cv&
IF bytesperpixel& = 1 THEN
FOR c& = 0 TO 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
cv& = _PALETTECOLOR(c&, image&) ' color attribute to read.
b$ = b$ + CHR$(_BLUE32(cv&)) + CHR$(_GREEN32(cv&)) + CHR$(_RED32(cv&)) + CHR$(0) 'spacer byte
NEXT
END IF
MID$(b$, 11, 4) = MKL$(LEN(b$)) ' image pixel data offset(BMP header)
DIM lastsource&: lastsource& = _SOURCE
_SOURCE image&
DIM padder$
IF ((x& * 3) MOD 4) THEN padder$ = STRING$(4 - ((x& * 3) MOD 4), 0)
DIM px&, py&, r$, d$
FOR py& = y& - 1 TO 0 STEP -1 ' read JPG image pixel color data
r$ = ""
FOR px& = 0 TO x& - 1
c& = POINT(px&, py&) 'POINT 32 bit values are large LONG values
IF bytesperpixel& = 1 THEN r$ = r$ + CHR$(c&) ELSE r$ = r$ + LEFT$(MKL$(c&), 3)
NEXT px&
d$ = d$ + r$ + padder$
NEXT py&
_SOURCE lastsource&
MID$(b$, 35, 4) = MKL$(LEN(d$)) ' image size(BMP header)
b$ = b$ + d$ ' total file data bytes to create file
MID$(b$, 3, 4) = MKL$(LEN(b$)) ' size of data file(BMP header)
DIM ext$
IF LCASE$(RIGHT$(filename$, 4)) <> ".bmp" THEN ext$ = ".bmp"
DIM f&: f& = FREEFILE
OPEN filename$ + ext$ FOR OUTPUT AS #f&: CLOSE #f& ' erases an existing file
OPEN filename$ + ext$ FOR BINARY AS #f&
PUT #f&, , b$
CLOSE #f&
END SUB
FUNCTION GetColorDelta~& (color1 AS _UNSIGNED LONG, color2 AS _UNSIGNED LONG)
GetColorDelta = ABS(_RED32(color1) - _RED32(color2)) + ABS(_GREEN32(color1) - _GREEN32(color2)) + ABS(_BLUE32(color1) - _BLUE32(color2)) + ABS(_ALPHA32(color1) - _ALPHA32(color2))
END FUNCTION
' Same as AssertImage() but is a bit more forgiving
SUB AssertImage2 (originalActualImage AS LONG, expectedFileName AS STRING, toleranceLimit AS LONG)
DIM actualImage AS LONG
DIM ResultsDir AS STRING, TestPrefix AS STRING
ResultsDir = COMMAND$(1)
TestPrefix = COMMAND$(2)
' Make sure the test result will be seen
_DEST _CONSOLE
' Convert to 32-bit for comparisons
actualImage = _NEWIMAGE(_WIDTH(originalActualImage), _HEIGHT(originalActualImage), 32)
_PUTIMAGE , originalActualImage, actualImage
'First save the result
IF LEN(ResultsDir) THEN _SAVEIMAGE ResultsDir + "/" + TestPrefix + "_" + expectedFileName + "_result.bmp", actualImage
'Compare both images, print whether they are identical
DIM expectedImage AS LONG
expectedImage = _LOADIMAGE(expectedFileName, 32)
DIM actual AS _MEM, expected AS _MEM
actual = _MEMIMAGE(actualImage)
expected = _MEMIMAGE(expectedImage)
IF _WIDTH(actualImage) <> _WIDTH(expectedImage) THEN
PRINT "Failure! Image width differs, actual:"; _WIDTH(actualImage); ", Expected:"; _WIDTH(expectedImage)
GOTO freeImages
END IF
IF _HEIGHT(actualImage) <> _HEIGHT(expectedImage) THEN
PRINT "Failure! Image height differs, actual:"; _HEIGHT(actualImage); ", Expected:"; _HEIGHT(expectedImage)
GOTO freeImages
END IF
IF actual.SIZE <> expected.SIZE THEN
PRINT "Failure! Image sizes differ, Actual:"; actual.SIZE; ", Expected:"; expected.SIZE
GOTO freeImages
END IF
DIM w&: w& = _WIDTH(expectedImage)
DIM h&: h& = _HEIGHT(expectedImage)
DIM x&, y&, pixelOffset AS _OFFSET
DIM AS _UNSIGNED LONG actualPixel, expectedPixel
FOR x& = 0 TO w& - 1
FOR y& = 0 TO h& - 1
pixelOffset = (y& * w& + x&) * 4
actualPixel = _MEMGET(actual, actual.OFFSET + pixelOffset, _UNSIGNED LONG)
expectedPixel = _MEMGET(expected, expected.OFFSET + pixelOffset, _UNSIGNED LONG)
IF actualPixel <> expectedPixel _ANDALSO GetColorDelta(actualPixel, expectedPixel) > toleranceLimit THEN
PRINT "Failure! Image pixels at ("; x&; ","; y&; ") differ, actual: 0x"; HEX$(actualPixel); ", expected: 0x"; HEX$(expectedPixel)
GOTO freeImages
END IF
NEXT
NEXT
PRINT "Success, images are identical!"
freeImages:
_MEMFREE actual
_MEMFREE expected
_FREEIMAGE actualImage
END SUB