diff --git a/.github/workflows/cibuildwheels.yml b/.github/workflows/cibuildwheels.yml index 4fd6ffa..8e32a18 100644 --- a/.github/workflows/cibuildwheels.yml +++ b/.github/workflows/cibuildwheels.yml @@ -60,7 +60,7 @@ jobs: CIBW_BUILD: 'cp38-win_amd64 cp39-win_amd64 cp310-win_amd64 cp311-win_amd64' CIBW_BEFORE_TEST: python -m pip install --upgrade pip && python -m pip install -r requirements-test.txt CIBW_TEST_COMMAND: > - cmd /V /C "set BLOSC_TRACE=1 && python {project}/examples/roundtrip.py {project}/examples/MI04_020751.tif" + cmd /V /C "set BLOSC_TRACE=1 && python -m pytest" - name: Build wheels (Linux / Mac OSX x86_64) if: ${{ matrix.os != 'windows-latest'}} @@ -72,7 +72,7 @@ jobs: CIBW_BUILD: 'cp39-* cp310-* cp311-* cp312-*' CIBW_BEFORE_TEST: python -m pip install --upgrade pip && python -m pip install -r requirements-test.txt CIBW_TEST_COMMAND: > - BLOSC_TRACE=1 python {project}/examples/roundtrip.py {project}/examples/MI04_020751.tif + BLOSC_TRACE=1 python -m pytest CIBW_ARCHS_LINUX: ${{ matrix.arch }} CIBW_ARCHS_MACOS: "x86_64" diff --git a/README.md b/README.md index e60927e..422617a 100644 --- a/README.md +++ b/README.md @@ -61,45 +61,32 @@ The following parameters are available for compression for grok, with its defaul 'tile_size': (0, 0), 'tile_offset': (0, 0), - # 'numlayers': 0, # blosc2_grok C func set_params will still receive this param 'quality_mode': None, 'quality_layers': np.zeros(0, dtype=np.float64), - 'csty': 0, - 'numgbits': 2, + * 'numgbits': 2, # Equivalent to -N, -guard_bits 'progression': "LRCP", 'num_resolutions': 6, 'codeblock_size': (64, 64), - 'codeblock_style': 0, - 'irreversible': False, # blosc2_grok C func set_params will still receive this param - 'roi_compno': -1, - 'roi_shift': 0, + 'irreversible': + * 'roi_compno': -1, # Together with 'roi_shift' it is equivalent to -R, -ROI + * 'roi_shift': 0, 'precinct_size': (0, 0), 'offset': (0, 0), - 'subsampling_dx': 1, - 'subsampling_dy': 1, - 'decod_format': GrkFileFmt.GRK_FMT_UNK, - 'cod_format': GrkFileFmt.GRK_FMT_UNK, - 'enableTilePartGeneration': False, - 'newTilePartProgressionDivider': 0, + * 'decod_format': GrkFileFmt.GRK_FMT_UNK, + * 'cod_format': GrkFileFmt.GRK_FMT_UNK, + * 'enableTilePartGeneration': False, # See https://github.com/GrokImageCompression/grok/blob/a84ac2592e581405a976a00cf9e6f03cab7e2481/src/lib/core/grok.h#L975 'mct': 0, - 'max_cs_size': 0, - 'max_comp_size': 0, - 'rsiz': GrkProfile.GRK_PROFILE_NONE, - 'framerate': 0, - 'apply_icc_': False, - 'rateControlAlgorithm': GrkRateControl.BISECT, - 'numThreads': 0, - 'deviceId': 0, - 'duration': 0, - 'kernelBuildOptions': 0, - 'repeats': 1, - 'plt': False, - 'tlm': False, - 'verbose': False, - 'sharedMemoryInterface': False, - -TODO: Complete this list, specially add the `*` marks. -TODO: Remove the ones that are not in Pillow nor in the grok page above. Or document them right here? + * 'max_cs_size': 0, # See https://github.com/GrokImageCompression/grok/blob/a84ac2592e581405a976a00cf9e6f03cab7e2481/src/lib/core/grok.h#L975 + * 'max_comp_size': 0, # See https://github.com/GrokImageCompression/grok/blob/a84ac2592e581405a976a00cf9e6f03cab7e2481/src/lib/core/grok.h#L975 + * 'rsiz': GrkProfile.GRK_PROFILE_NONE, # Equivalent to -Z, -rsiz + * 'framerate': 0, + * 'apply_icc_': False, # Equivalent to -f, -apply_icc + * 'rateControlAlgorithm': GrkRateControl.BISECT, + * 'deviceId': 0, # Equivalent to -G, -device_id + * 'duration': 0, # Equivalent to -J, -duration + * 'repeats': 1, # Equivalent to -e, -repetitions + * 'verbose': False, + * 'sharedMemoryInterface': False, # See https://github.com/GrokImageCompression/grok/blob/a84ac2592e581405a976a00cf9e6f03cab7e2481/src/lib/core/grok.h#L975 ## More examples diff --git a/blosc2_grok/__init__.py b/blosc2_grok/__init__.py index a64d9fd..dd8060d 100644 --- a/blosc2_grok/__init__.py +++ b/blosc2_grok/__init__.py @@ -107,47 +107,37 @@ def destroy(): lib.blosc2_grok_destroy() -# TODO: change these by the actual defaults params_defaults = { 'tile_size': (0, 0), 'tile_offset': (0, 0), # 'numlayers': 0, # blosc2_grok C func set_params will still receive this param 'quality_mode': None, 'quality_layers': np.zeros(0, dtype=np.float64), - 'csty': 0, 'numgbits': 2, 'progression': "LRCP", 'num_resolutions': 6, 'codeblock_size': (64, 64), + 'irreversible': False, # 10 - 19 - 'codeblock_style': 0, - # 'irreversible': False, # blosc2_grok C func set_params will still receive this param 'roi_compno': -1, 'roi_shift': 0, 'precinct_size': (0, 0), 'offset': (0, 0), - 'subsampling_dx': 1, - 'subsampling_dy': 1, 'decod_format': GrkFileFmt.GRK_FMT_UNK, 'cod_format': GrkFileFmt.GRK_FMT_UNK, - # 20 - 29 'enableTilePartGeneration': False, - 'newTilePartProgressionDivider': 0, 'mct': 0, 'max_cs_size': 0, 'max_comp_size': 0, + # 20 - 29 'rsiz': GrkProfile.GRK_PROFILE_NONE, 'framerate': 0, 'apply_icc_': False, 'rateControlAlgorithm': GrkRateControl.BISECT, - 'numThreads': 0, - # 30 - 37 + # 'numThreads': 0, # C func will still receive this param 'deviceId': 0, 'duration': 0, - 'kernelBuildOptions': 0, 'repeats': 1, - 'plt': False, - 'tlm': False, 'verbose': False, 'sharedMemoryInterface': False, } @@ -171,33 +161,34 @@ def set_params_defaults(**kwargs): args[3] = args[3].encode('utf-8') args[2] = args[4].shape[0] - args.insert(11, False) # irreversible param is deactivated for now + args[6] = args[6].encode('utf-8') - args[7] = args[7].encode('utf-8') + # Insert numThreads + args.insert(24, 0) # Convert tuples to desired NumPy arrays args[0] = np.array(args[0], dtype=np.int64) args[1] = np.array(args[1], dtype=np.int64) - args[9] = np.array(args[9], dtype=np.int64) - args[14] = np.array(args[14], dtype=np.int64) - args[15] = np.array(args[15], dtype=np.int64) + args[8] = np.array(args[8], dtype=np.int64) + args[12] = np.array(args[2], dtype=np.int64) + args[13] = np.array(args[13], dtype=np.int64) # Get value of enumerate - args[18] = args[18].value - args[19] = args[19].value - args[25] = args[25].value - args[28] = args[28].value + args[14] = args[14].value + args[15] = args[15].value + args[20] = args[20].value + args[23] = args[23].value lib.blosc2_grok_set_default_params.argtypes = ([np.ctypeslib.ndpointer(dtype=np.int64)] * 2 + [ctypes.c_int] + [ctypes.c_char_p] + [np.ctypeslib.ndpointer(dtype=np.float64)] + - [ctypes.c_int] * 2 + [ctypes.c_char_p] + - [ctypes.c_int] + [np.ctypeslib.ndpointer(dtype=np.int64)] + [ctypes.c_int] + + [ctypes.c_int] + [ctypes.c_char_p] + + [ctypes.c_int] + [np.ctypeslib.ndpointer(dtype=np.int64)] + [ctypes.c_bool] + [ctypes.c_int] * 2 + [np.ctypeslib.ndpointer(dtype=np.int64)] + - [np.ctypeslib.ndpointer(dtype=np.int64)] + [ctypes.c_int] + - [ctypes.c_int] * 2 + + [np.ctypeslib.ndpointer(dtype=np.int64)] + + [ctypes.c_int] + [ctypes.c_int] + [ctypes.c_bool] + - [ctypes.c_int] * 6 + [ctypes.c_bool] + - [ctypes.c_int] * 6 + [ctypes.c_bool] * 4) + [ctypes.c_int] * 5 + [ctypes.c_bool] + + [ctypes.c_int] * 5 + [ctypes.c_bool] * 2) lib.blosc2_grok_set_default_params(*args) diff --git a/src/blosc2_grok.cpp b/src/blosc2_grok.cpp index 56b9ba9..e4bd3a1 100644 --- a/src/blosc2_grok.cpp +++ b/src/blosc2_grok.cpp @@ -250,18 +250,18 @@ void blosc2_grok_init(uint32_t nthreads, bool verbose) { void blosc2_grok_set_default_params(const int64_t *tile_size, const int64_t *tile_offset, int numlayers, char *quality_mode, double *quality_layers, - int csty, int numgbits, char *progression, - int num_resolutions, int64_t *codeblock_size, int codeblock_style, + int numgbits, char *progression, + int num_resolutions, int64_t *codeblock_size, bool irreversible, int roi_compno, int roi_shift, const int64_t *precinct_size, - const int64_t *offset, int subsampling_dx, - int subsampling_dy, GRK_SUPPORTED_FILE_FMT decod_format, + const int64_t *offset, + GRK_SUPPORTED_FILE_FMT decod_format, GRK_SUPPORTED_FILE_FMT cod_format, bool enableTilePartGeneration, - int newTilePartProgressionDivider, int mct, int max_cs_size, + int mct, int max_cs_size, int max_comp_size, int rsiz, int framerate, bool apply_icc_, GRK_RATE_CONTROL_ALGORITHM rateControlAlgorithm, int numThreads, int deviceId, - int duration, int kernelBuildOptions, int repeats, bool writePLT, - bool writeTLM, bool verbose, bool sharedMemoryInterface) { + int duration, int repeats, + bool verbose, bool sharedMemoryInterface) { if (tile_size[0] == 0 && tile_size[1] == 0) { GRK_CPARAMETERS_DEFAULTS.tile_size_on = false; } else { @@ -297,7 +297,7 @@ void blosc2_grok_set_default_params(const int64_t *tile_size, const int64_t *til } GRK_CPARAMETERS_DEFAULTS.num_comments = num_comments;*/ - GRK_CPARAMETERS_DEFAULTS.csty = csty; + // GRK_CPARAMETERS_DEFAULTS.csty = csty; GRK_CPARAMETERS_DEFAULTS.numgbits = numgbits; if (strcmp(progression, "LRCP") == 0) { GRK_CPARAMETERS_DEFAULTS.prog_order = GRK_LRCP; @@ -332,18 +332,18 @@ void blosc2_grok_set_default_params(const int64_t *tile_size, const int64_t *til GRK_CPARAMETERS_DEFAULTS.roi_compno = roi_compno; GRK_CPARAMETERS_DEFAULTS.roi_shift = roi_shift; - GRK_CPARAMETERS_DEFAULTS.cblk_sty = codeblock_style; + // GRK_CPARAMETERS_DEFAULTS.cblk_sty = codeblock_style; GRK_CPARAMETERS_DEFAULTS.image_offset_x0 = offset[0]; GRK_CPARAMETERS_DEFAULTS.image_offset_y0 = offset[1]; - GRK_CPARAMETERS_DEFAULTS.subsampling_dx = subsampling_dx; - GRK_CPARAMETERS_DEFAULTS.subsampling_dy = subsampling_dy; + // GRK_CPARAMETERS_DEFAULTS.subsampling_dx = subsampling_dx; + // GRK_CPARAMETERS_DEFAULTS.subsampling_dy = subsampling_dy; GRK_CPARAMETERS_DEFAULTS.decod_format = decod_format; GRK_CPARAMETERS_DEFAULTS.cod_format = cod_format; // GRK_CPARAMETERS_DEFAULTS.raw_cp = raw_cp; GRK_CPARAMETERS_DEFAULTS.enableTilePartGeneration = enableTilePartGeneration; - GRK_CPARAMETERS_DEFAULTS.newTilePartProgressionDivider = newTilePartProgressionDivider; + // GRK_CPARAMETERS_DEFAULTS.newTilePartProgressionDivider = newTilePartProgressionDivider; GRK_CPARAMETERS_DEFAULTS.mct = mct; // GRK_CPARAMETERS_DEFAULTS.mct_data = mct_data; @@ -367,10 +367,10 @@ void blosc2_grok_set_default_params(const int64_t *tile_size, const int64_t *til GRK_CPARAMETERS_DEFAULTS.deviceId = deviceId; GRK_CPARAMETERS_DEFAULTS.duration = duration; - GRK_CPARAMETERS_DEFAULTS.kernelBuildOptions = kernelBuildOptions; + // GRK_CPARAMETERS_DEFAULTS.kernelBuildOptions = kernelBuildOptions; GRK_CPARAMETERS_DEFAULTS.repeats = repeats; - GRK_CPARAMETERS_DEFAULTS.writePLT = writePLT; - GRK_CPARAMETERS_DEFAULTS.writeTLM = writeTLM; + // GRK_CPARAMETERS_DEFAULTS.writePLT = writePLT; + // GRK_CPARAMETERS_DEFAULTS.writeTLM = writeTLM; GRK_CPARAMETERS_DEFAULTS.verbose = verbose; GRK_CPARAMETERS_DEFAULTS.sharedMemoryInterface = sharedMemoryInterface; diff --git a/src/blosc2_grok.h b/src/blosc2_grok.h index f77fb69..dd84037 100644 --- a/src/blosc2_grok.h +++ b/src/blosc2_grok.h @@ -31,18 +31,18 @@ void blosc2_grok_destroy(); void blosc2_grok_set_default_params(const int64_t *tile_size, const int64_t *tile_offset, int numlayers, char *quality_mode, double *quality_layers, - int csty, int numgbits, char *progression, - int num_resolutions, int64_t *codeblock_size, int codeblock_style, + int numgbits, char *progression, + int num_resolutions, int64_t *codeblock_size, bool irreversible, int roi_compno, int roi_shift, const int64_t *precinct_size, - const int64_t *offset, int subsampling_dx, - int subsampling_dy, GRK_SUPPORTED_FILE_FMT decod_format, + const int64_t *offset, + GRK_SUPPORTED_FILE_FMT decod_format, GRK_SUPPORTED_FILE_FMT cod_format, bool enableTilePartGeneration, - int newTilePartProgressionDivider, int mct, int max_cs_size, + int mct, int max_cs_size, int max_comp_size, int rsiz, int framerate, bool apply_icc_, GRK_RATE_CONTROL_ALGORITHM rateControlAlgorithm, int numThreads, int deviceId, - int duration, int kernelBuildOptions, int repeats, bool writePLT, - bool writeTLM, bool verbose, bool sharedMemoryInterface); + int duration, int repeats, + bool verbose, bool sharedMemoryInterface); #ifdef __cplusplus diff --git a/tests/test_jp2.py b/tests/test_jp2.py index 19fc201..3651d96 100644 --- a/tests/test_jp2.py +++ b/tests/test_jp2.py @@ -30,16 +30,16 @@ ({'enableTilePartGeneration': True}), ({'tile_size': (1009, 1000)}), ({'tile_size': (1009, 1000), 'enableTilePartGeneration': True}), - # ({'csty': 1}), ({'numgbits': 4}), ({'progression': 'RLCP'}), ({'progression': 'RPCL'}), ({'progression': 'PCRL'}), ({'progression': 'CPRL'}), ({'num_resolutions': 8}), + ({'irreversible': True}), ({'codeblock_size': (4, 4)}), ({'codeblock_size': (8, 64)}), - ({'codeblock_size': (256, 8), 'codeblock_style': 1}), + ({'codeblock_size': (256, 8)}), ({'roi_compno': 0}), ({'roi_compno': 1}), ({'roi_compno': 2}), @@ -47,26 +47,22 @@ ({'roi_shift': 8}), ({'precinct_size': (32, 32)}), ({'precinct_size': (64, 64)}), + ({'precinct_size': (128, 128)}), ({'offset': (33, 40)}), - ({'subsampling_dx': 2, 'subsampling_dy': 2}), - ({'newTilePartProgressionDivider': 20}), - ({'newTilePartProgressionDivider': 4, 'enableTilePartGeneration': True}), - ({'newTilePartProgressionDivider': 1}), - ({'newTilePartProgressionDivider': 1, 'enableTilePartGeneration': True}), ({'mct': 1}), + ({'mct': 1, 'irreversible': True}), ({'max_cs_size': 256}), ({'max_cs_size': 256, 'quality_mode': 'rates', 'quality_layers': np.array([5], dtype=np.float64)}), - # ({'max_comp_size': 2}), # Don't really know why this fails - # ({'rsiz': 8}), # Don't know how to use this yet + ({'max_comp_size': 10**9}), + ({'rsiz': blosc2_grok.GrkProfile.GRK_PROFILE_0}), + ({'rsiz': blosc2_grok.GrkProfile.GRK_PROFILE_1}), # ({'framerate': 8}), # Would make sense if we had more than one frame ({'apply_icc_': True}), - ({'numThreads': 4}), + # ({'numThreads': 4}), # Deactivated until we can actually use it # ({'deviceId': 8}), # Meant for multi-GPU systems ({'duration': 1}), - # ({'kernelBuildOptions': 8}), # NI - ({'repeats': 2}), # NI - ({'plt': True}), # TO-DO: check header - ({'tlm': True}), # NI + ({'repeats': 2}), + ({'repeats': 0}), ({'sharedMemoryInterface': True}), ], ) @@ -92,7 +88,6 @@ def test_jp2(image, args): cparams = { 'codec': 160, - # 'nthreads': nthreads, 'filters': [], 'splitmode': blosc2.SplitMode.NEVER_SPLIT, } @@ -110,7 +105,7 @@ def test_jp2(image, args): print(bl_array.schunk.cratio) if kwargs.get('quality_mode', None) is None: - if kwargs.get('max_cs_size', None) is None: + if kwargs.get('max_cs_size', None) is None and not kwargs.get('irreversible', False): np.testing.assert_array_equal(bl_array[...], np_array) else: if kwargs['quality_mode'] == 'rates' and kwargs.get('max_cs_size', None) is None: