martinbenes1996/jpeglib

Verify dtype in `jpeglib.from_spatial`

Closed this issue · 1 comments

Although the docstring of jpeglib.from_spatial suggests that the input dtype should be uint8, jpeglib allows constructing objects from other dtypes. This can have undesired effects. For example, writing and loading such an array results in a completely different image. Please find a minimal working example below. A fix could be to raise an error for unexpected dtypes.

# Create random 8x8 integer block
filepath = "/tmp/demo.jpg"
rng = np.random.default_rng(12345)
spatial_block = rng.integers(low=0, high=256, size=(8, 8))
assert spatial_block.min() >= 0
assert spatial_block.max() <= 255

print("Original block")
print(spatial_block)
print()

# Create a jpeglib object. Note that the input dtype is int64.
im = jpeglib.from_spatial(spatial_block[:, :, None].astype(int))
print("im.spatial")
print(im.spatial[:, :, 0])
print()

# Write and load jpeglib object
im.write_spatial(filepath, qt=100)
spatial_recovered = jpeglib.read_spatial(filepath).spatial[:, :, 0]
print("spatial recovered")
print(spatial_recovered)
print()

# Create an jpeglib object with uint8 input array, write, and reload
jpeglib.from_spatial(spatial_block[:, :, None].astype(np.uint8)).write_spatial(filepath, qt=100)
spatial_uint8_recovered = jpeglib.read_spatial(filepath).spatial[:, :, 0]
print("spatial uint8 recovered")
print(spatial_uint8_recovered)

Output

Original block
[[178  58 201  81  52 204 164 173]
 [253 100 214  85 145 153  54  47]
 [ 58 172 157 241 180  63 234 242]
 [187 170  33  24  68 113  18 226]
 [121 178  54  83  29 187 198  56]
 [183  20 100  40 190  87 121 119]
 [121  68 142 208 127  49   6  33]
 [ 20  23  31 153 206 218 167 154]]

im.spatial
[[178  58 201  81  52 204 164 173]
 [253 100 214  85 145 153  54  47]
 [ 58 172 157 241 180  63 234 242]
 [187 170  33  24  68 113  18 226]
 [121 178  54  83  29 187 198  56]
 [183  20 100  40 190  87 121 119]
 [121  68 142 208 127  49   6  33]
 [ 20  23  31 153 206 218 167 154]]

spatial recovered
[[178   0   0   0   0   0   0   0]
 [ 58   0   1   0   0   0   0   0]
 [201   0   0   1   0   0   0   0]
 [ 81   0   0   0   0   0   0   0]
 [ 52   0   0   0   0   0   0   0]
 [205   0   0   0   1   0   0   0]
 [164   0   0   0   0   0   0   0]
 [173   0   0   0   0   1   0   0]]

spatial uint8 recovered
[[178  58 201  81  52 204 164 174]
 [253 100 214  85 145 153  54  47]
 [ 58 173 157 241 180  63 234 242]
 [187 170  33  24  68 113  18 226]
 [121 178  54  83  29 187 199  56]
 [183  20 100  40 190  87 121 118]
 [121  68 142 208 127  49   6  33]
 [ 20  23  32 153 207 218 167 154]]

Thank you for your report.

Checking the dtype in from_spatial is now added to dev branch.

It will be part of the next release.