Merge pull request #1680 from pijyoi/rgba_endian

Fix CI tests for big-endian architectures
This commit is contained in:
Ogi Moore 2021-04-01 20:37:06 -07:00 committed by GitHub
commit 07a99cb443
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 32 deletions

View File

@ -1242,9 +1242,11 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False, output=None
# decide channel order
if useRGBA:
order = [0,1,2,3] # array comes out RGBA
dst_order = [0, 1, 2, 3] # R,G,B,A
elif sys.byteorder == 'little':
dst_order = [2, 1, 0, 3] # B,G,R,A (ARGB32 little endian)
else:
order = [2,1,0,3] # for some reason, the colors line up as BGR in the final image.
dst_order = [1, 2, 3, 0] # A,R,G,B (ARGB32 big endian)
# copy data into image array
fastpath = try_fastpath_argb(xp, data, imgData, useRGBA)
@ -1256,13 +1258,13 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False, output=None
# imgData[..., :3] = data[..., xp.newaxis]
# ..but it turns out this is faster:
for i in range(3):
imgData[..., i] = data
imgData[..., dst_order[i]] = data
elif data.shape[2] == 1:
for i in range(3):
imgData[..., i] = data[..., 0]
imgData[..., dst_order[i]] = data[..., 0]
else:
for i in range(0, data.shape[2]):
imgData[..., i] = data[..., order[i]]
imgData[..., dst_order[i]] = data[..., i]
profile('reorder channels')
@ -1272,16 +1274,16 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False, output=None
else:
alpha = False
if not fastpath: # fastpath has already filled it in
imgData[..., 3] = 255
imgData[..., dst_order[3]] = 255
# apply nan mask through alpha channel
if nanMask is not None:
alpha = True
# Workaround for https://github.com/cupy/cupy/issues/4693
if xp == cp:
imgData[nanMask, :, 3] = 0
imgData[nanMask, :, dst_order[3]] = 0
else:
imgData[nanMask, 3] = 0
imgData[nanMask, dst_order[3]] = 0
profile('alpha channel')
return imgData, alpha

View File

@ -145,8 +145,13 @@ def assertImageApproved(image, standardFile, message=None, **kwargs):
image = fn.imageToArray(qimg, copy=False, transpose=False)
# transpose BGRA to RGBA
image = image[..., [2, 1, 0, 3]]
# the standard images seem to have their Red and Blue swapped
if sys.byteorder == 'little':
# transpose B,G,R,A to R,G,B,A
image = image[..., [2, 1, 0, 3]]
else:
# transpose A,R,G,B to A,B,G,R
image = image[..., [0, 3, 2, 1]]
if message is None:
code = inspect.currentframe().f_back.f_code

View File

@ -147,6 +147,17 @@ def test_rescaleData():
assert np.allclose(s1, s2)
def makeARGB(*args, **kwds):
img, alpha = pg.makeARGB(*args, **kwds)
if kwds.get('useRGBA'): # endian independent
out = img
elif sys.byteorder == 'little': # little-endian ARGB32 to B,G,R,A
out = img
else: # big-endian ARGB32 to B,G,R,A
out = img[..., [3, 2, 1, 0]]
return out, alpha
def test_makeARGB():
# Many parameters to test here:
# * data dtype (ubyte, uint16, float, others)
@ -193,55 +204,55 @@ def test_makeARGB():
# uint8 data tests
im1 = np.arange(256).astype('ubyte').reshape(256, 1)
im2, alpha = pg.makeARGB(im1, levels=(0, 255))
im2, alpha = makeARGB(im1, levels=(0, 255))
checkImage(im2, im1, alpha, False)
im3, alpha = pg.makeARGB(im1, levels=(0.0, 255.0))
im3, alpha = makeARGB(im1, levels=(0.0, 255.0))
checkImage(im3, im1, alpha, False)
im4, alpha = pg.makeARGB(im1, levels=(255, 0))
im4, alpha = makeARGB(im1, levels=(255, 0))
checkImage(im4, 255-im1, alpha, False)
im5, alpha = pg.makeARGB(np.concatenate([im1]*3, axis=1), levels=[(0, 255), (0.0, 255.0), (255, 0)])
im5, alpha = makeARGB(np.concatenate([im1]*3, axis=1), levels=[(0, 255), (0.0, 255.0), (255, 0)])
checkImage(im5, np.concatenate([im1, im1, 255-im1], axis=1), alpha, False)
im2, alpha = pg.makeARGB(im1, levels=(128,383))
im2, alpha = makeARGB(im1, levels=(128,383))
checkImage(im2[:128], 0, alpha, False)
checkImage(im2[128:], im1[:128], alpha, False)
# uint8 data + uint8 LUT
lut = np.arange(256)[::-1].astype(np.uint8)
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, lut, alpha, False)
# lut larger than maxint
lut = np.arange(511).astype(np.uint8)
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, lut[::2], alpha, False)
# lut smaller than maxint
lut = np.arange(128).astype(np.uint8)
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, np.linspace(0, 127.5, 256, dtype='ubyte'), alpha, False)
# lut + levels
lut = np.arange(256)[::-1].astype(np.uint8)
im2, alpha = pg.makeARGB(im1, lut=lut, levels=[-128, 384])
im2, alpha = makeARGB(im1, lut=lut, levels=[-128, 384])
checkImage(im2, np.linspace(191.5, 64.5, 256, dtype='ubyte'), alpha, False)
im2, alpha = pg.makeARGB(im1, lut=lut, levels=[64, 192])
im2, alpha = makeARGB(im1, lut=lut, levels=[64, 192])
checkImage(im2, np.clip(np.linspace(384.5, -127.5, 256), 0, 255).astype('ubyte'), alpha, False)
# uint8 data + uint16 LUT
lut = np.arange(4096)[::-1].astype(np.uint16) // 16
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, np.arange(256)[::-1].astype('ubyte'), alpha, False)
# uint8 data + float LUT
lut = np.linspace(10., 137., 256)
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, lut.astype('ubyte'), alpha, False)
# uint8 data + 2D LUT
@ -249,39 +260,39 @@ def test_makeARGB():
lut[:,0] = np.arange(256)
lut[:,1] = np.arange(256)[::-1]
lut[:,2] = 7
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, lut[:,None,::-1], alpha, False)
# check useRGBA
im2, alpha = pg.makeARGB(im1, lut=lut, useRGBA=True)
im2, alpha = makeARGB(im1, lut=lut, useRGBA=True)
checkImage(im2, lut[:,None,:], alpha, False)
# uint16 data tests
im1 = np.arange(0, 2**16, 256).astype('uint16')[:, None]
im2, alpha = pg.makeARGB(im1, levels=(512, 2**16))
im2, alpha = makeARGB(im1, levels=(512, 2**16))
checkImage(im2, np.clip(np.linspace(-2, 253, 256), 0, 255).astype('ubyte'), alpha, False)
lut = (np.arange(512, 2**16)[::-1] // 256).astype('ubyte')
im2, alpha = pg.makeARGB(im1, lut=lut, levels=(512, 2**16-256))
im2, alpha = makeARGB(im1, lut=lut, levels=(512, 2**16-256))
checkImage(im2, np.clip(np.linspace(257, 2, 256), 0, 255).astype('ubyte'), alpha, False)
lut = np.zeros(2**16, dtype='ubyte')
lut[1000:1256] = np.arange(256)
lut[1256:] = 255
im1 = np.arange(1000, 1256).astype('uint16')[:, None]
im2, alpha = pg.makeARGB(im1, lut=lut)
im2, alpha = makeARGB(im1, lut=lut)
checkImage(im2, np.arange(256).astype('ubyte'), alpha, False)
# float data tests
im1 = np.linspace(1.0, 17.0, 256)[:, None]
im2, alpha = pg.makeARGB(im1, levels=(5.0, 13.0))
im2, alpha = makeARGB(im1, levels=(5.0, 13.0))
checkImage(im2, np.clip(np.linspace(-128, 383, 256), 0, 255).astype('ubyte'), alpha, False)
lut = (np.arange(1280)[::-1] // 10).astype('ubyte')
im2, alpha = pg.makeARGB(im1, lut=lut, levels=(1, 17))
im2, alpha = makeARGB(im1, lut=lut, levels=(1, 17))
checkImage(im2, np.linspace(127.5, 0, 256).astype('ubyte'), alpha, False)
# nans in image
@ -289,7 +300,7 @@ def test_makeARGB():
# 2d input image, one pixel is nan
im1 = np.ones((10, 12))
im1[3, 5] = np.nan
im2, alpha = pg.makeARGB(im1, levels=(0, 1))
im2, alpha = makeARGB(im1, levels=(0, 1))
assert alpha
assert im2[3, 5, 3] == 0 # nan pixel is transparent
assert im2[0, 0, 3] == 255 # doesn't affect other pixels
@ -297,7 +308,7 @@ def test_makeARGB():
# 3d RGB input image, any color channel of a pixel is nan
im1 = np.ones((10, 12, 3))
im1[3, 5, 1] = np.nan
im2, alpha = pg.makeARGB(im1, levels=(0, 1))
im2, alpha = makeARGB(im1, levels=(0, 1))
assert alpha
assert im2[3, 5, 3] == 0 # nan pixel is transparent
assert im2[0, 0, 3] == 255 # doesn't affect other pixels
@ -305,7 +316,7 @@ def test_makeARGB():
# 3d RGBA input image, any color channel of a pixel is nan
im1 = np.ones((10, 12, 4))
im1[3, 5, 1] = np.nan
im2, alpha = pg.makeARGB(im1, levels=(0, 1), useRGBA=True)
im2, alpha = makeARGB(im1, levels=(0, 1), useRGBA=True)
assert alpha
assert im2[3, 5, 3] == 0 # nan pixel is transparent