Skip to content

Commit

Permalink
Change back to the compressed version of normal_map.tif as decompress…
Browse files Browse the repository at this point in the history
…ed it lost the RGBX colour mode. Add RGBX support - convert to RGBA. Document RGBX support
  • Loading branch information
mel-mason committed Mar 5, 2024
1 parent 71a0872 commit aab986c
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 7 deletions.
5 changes: 5 additions & 0 deletions docs/jp2_colour_management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ The ``kdu_compress`` :ref:`command options <kdu_compress-options>` we use do not

As very few of our input images have an alpha channel, and we have not encountered failing cases in live data (as opposed to constructed test data), this is not a priority for us. We just make sure to check RGBA JP2 conversions are lossless, so we will catch any future failing cases.

RGBX colour mode
~~~~~~~~~~~~~~~~~~

I could not find a simple way to convert an RGBX TIFF to an RGBX JP2, though it's possible more work would produce one. In our particular use case it's always clear whether the image should be interpreted as RGBA or RGBX, so we convert RGBX images to RGBA, preserving all of the pixel data but not the colour mode. The program logs a warning when converting RGBX files because of this.

Colour profiles / modes not supported by JP2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
5 changes: 5 additions & 0 deletions image_processing/derivative_files_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ def generate_jp2_from_tiff(self, tiff_file, jp2_filepath):
if tiff_pil.mode == 'RGBA':
if kakadu.ALPHA_OPTION not in kakadu_options:
kakadu_options += [kakadu.ALPHA_OPTION]
elif tiff_pil.mode == 'RGBX':
self.log.warning('Input tiff has colour mode RGBX. It will be converted to RGBA')
if kakadu.ALPHA_OPTION not in kakadu_options:
kakadu_options += [kakadu.ALPHA_OPTION]


self.kakadu.kdu_compress(tiff_file, jp2_filepath, kakadu_options=kakadu_options)
self.log.debug('Lossless jp2 file {0} generated'.format(jp2_filepath))
Expand Down
4 changes: 3 additions & 1 deletion image_processing/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
GREYSCALE = 'L'
BITONAL = '1'
MONOTONE_COLOUR_MODES = [GREYSCALE, BITONAL]
ACCEPTED_COLOUR_MODES = ['RGB', 'RGBA', 'RGBX', 'I;16', GREYSCALE, BITONAL] # todo: are there any other modes we may have to consider? Need to add test for RGBX image
ACCEPTED_COLOUR_MODES = ['RGB', 'RGBA', 'RGBX', 'I;16', GREYSCALE, BITONAL]


def validate_jp2(image_file, output_file=None):
Expand Down Expand Up @@ -154,6 +154,8 @@ def check_colour_profiles_match(source_filepath, converted_filepath):
if source_image.mode != converted_image.mode:
if source_image.mode == BITONAL and converted_image.mode == GREYSCALE:
logger.info('Converted image is greyscale, not bitonal. This is expected')
elif source_image.mode == 'RGBX' and converted_image.mode == 'RGBA':
logger.info('Converted image in RGBA space, but was converted from RGBX. This is expected.')
else:
raise exceptions.ValidationError(
f'Converted file {converted_filepath} has different colour mode ({converted_image.mode}) from {source_filepath} ({source_image.mode})'
Expand Down
Binary file modified tests/data/normal_map.tif
Binary file not shown.
8 changes: 4 additions & 4 deletions tests/test_derivatives_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def test_creates_correct_files_from_jpg(self):
assert image_files_match(jp2_file, filepaths.LOSSLESS_JP2_FROM_STANDARD_JPG_XMP)
assert xmp_files_match(embedded_metadata_file, filepaths.STANDARD_JPG_XMP)

def test_converts_depthmap_tif_to_jpeg2000_losslessly(self):
def test_converts_i_16_tif_to_jpeg2000_losslessly(self):
"""
Check transformations of 16 bit depthmap images do not lose data
:return:
Expand All @@ -238,15 +238,15 @@ def test_converts_depthmap_tif_to_jpeg2000_losslessly(self):
assert os.path.isfile(output_file)
generator.check_conversion_was_lossless(filepaths.DEPTHMAP_TIF, output_file)

def test_converts_normalmap_tif_to_jpeg2000_losslessly(self):
def test_converts_rgbx_tif_to_jpeg2000_losslessly(self):
"""
Check transformations of RGBA normal map images do not lose data
Check transformations of RGBX normal map images do not lose data
:return:
"""
with temporary_folder() as output_folder:
generator = get_derivatives_generator()
output_file = os.path.join(output_folder, 'output.jp2')
# note that this method has specific handling for files with alpha channels that the direct converter method does not
# note that this method has specific handling for files with four channels that the direct converter method does not
generator.generate_jp2_from_tiff(filepaths.NORMALMAP_TIF, output_file)
assert os.path.isfile(output_file)
generator.check_conversion_was_lossless(filepaths.NORMALMAP_TIF, output_file)
6 changes: 4 additions & 2 deletions tests/test_utils/filepaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

# adobe rgb 1998 8 bit tiff file (our most common input format) + expected derivatives
STANDARD_TIF = 'tests/data/standard_adobe.tif'
DEPTHMAP_TIF = 'tests/data/depth_map.tif' # 16 bit (I;16) archiox image
NORMALMAP_TIF = 'tests/data/normal_map.tif' # RGBA archiox image
STANDARD_TIF_SINGLE_LAYER = 'tests/data/standard_adobe_tif_single_layer.tif' # same tif but without thumbnail
LOSSY_JP2_FROM_STANDARD_TIF = 'tests/data/standard_adobe_tif_lossy.jp2'
LOSSLESS_JP2_FROM_STANDARD_TIF_XMP = 'tests/data/standard_adobe_tif_xmp.jp2'
Expand Down Expand Up @@ -51,6 +49,10 @@

NO_PROFILE_TIF = 'tests/data/no_profile.tif'

# tifs from our archiox project, which can have unusual colour modes
DEPTHMAP_TIF = 'tests/data/depth_map.tif' # 16 bit (I;16) archiox image
NORMALMAP_TIF = 'tests/data/normal_map.tif' # RGBX archiox image (compressed, as decompression with Image Magick converts it to RGBA)

# just truncated files
INVALID_JP2 = 'tests/data/invalid.jp2'
INVALID_TIF = 'tests/data/invalid.tif'
Expand Down

0 comments on commit aab986c

Please sign in to comment.