47#include "../transform/ojph_colour.h"
48#include "../transform/ojph_transform.h"
57 : precinct_scratch(NULL), allocator(NULL), elastic_alloc(NULL)
112 OJPH_ERROR(0x00030011,
"number of tiles cannot exceed 65535");
117 ui32 num_tileparts = 0;
119 rect tile_rect, recon_tile_rect;
135 - recon_tile_rect.
org.
y;
151 - recon_tile_rect.
org.
x;
155 num_tileparts += tps;
178 for (
ui32 r = 0; r <= num_decomps; ++r)
181 log_PP.
w -= (r ? 1 : 0);
182 log_PP.
h -= (r ? 1 : 0);
187 max_ratio = 1 << max_ratio;
196 4 * ((max_ratio * max_ratio * 4 + 2) / 3);
213 ui32 num_tileparts = 0;
215 rect tile_rect, recon_tile_rect;
232 - recon_tile_rect.
org.
y;
249 - recon_tile_rect.
org.
x;
255 offset += recon_tile_rect.
siz.
w;
256 num_tileparts += tps;
296 bool imf2k = !reversible, imf4k = !reversible, imf8k = !reversible;
297 bool imf2kls = reversible, imf4kls = reversible, imf8kls = reversible;
302 if (ext.
x <= 2048 && ext.
y <= 1556)
304 if (ext.
x <= 4096 && ext.
y <= 3112)
306 if (ext.
x <= 8192 && ext.
y <= 6224)
309 if (!imf2kls && !imf4kls && !imf8kls)
311 "Image dimensions do not meet any of the lossless IMF profiles");
316 if (ext.
x <= 2048 && ext.
y <= 1556)
318 if (ext.
x <= 4096 && ext.
y <= 3112)
320 if (ext.
x <= 8192 && ext.
y <= 6224)
323 if (!imf2k && !imf4k && !imf8k)
325 "Image dimensions do not meet any of the lossy IMF profiles");
331 "For IMF profile, image offset (XOsiz, YOsiz) has to be 0.");
334 "For IMF profile, tile offset (XTOsiz, YTOsiz) has to be 0.");
337 "For IMF profile, the number of components has to be less "
339 bool test_ds1 =
true, test_ds2 =
true;
343 test_ds1 &= downsamping.
y == 1;
344 test_ds2 &= downsamping.
y == 1;
346 test_ds1 &= downsamping.
x == 1;
347 if (i == 1 || i == 2)
348 test_ds2 &= downsamping.
x == 2;
350 test_ds2 &= downsamping.
x == 1;
352 if (!test_ds1 && !test_ds2)
354 "For IMF profile, either no component downsampling is used,"
355 " or the x-dimension of the 2nd and 3rd components is downsampled"
363 test_bd &= bit_depth >= 8 && bit_depth <= 16 && is_signed ==
false;
367 "For IMF profile, compnent bit_depth has to be between"
368 " 8 and 16 bits inclusively, and the samples must be unsigned");
372 "For IMF profile, codeblock dimensions are restricted."
373 " Use \"-block_size {32,32}\" at the commandline");
378 for (
ui32 i = 1; i <= num_decomps; ++i)
383 "For IMF profile, precinct sizes are restricted."
384 " Use \"-precincts {128,128},{256,256}\" at the commandline");
388 "For IMF profile, the CPRL progression order must be used."
389 " Use \"-prog_order CPRL\".");
391 imf2k &= num_decomps <= 5;
392 imf2kls &= num_decomps <= 5;
393 imf4k &= num_decomps <= 6;
394 imf4kls &= num_decomps <= 6;
395 imf8k &= num_decomps <= 7;
396 imf8kls &= num_decomps <= 7;
398 if (num_decomps == 0 ||
399 (!imf2k && !imf4k && !imf8k && !imf2kls && !imf4kls && !imf8kls))
401 "Number of decompositions does not match the IMF profile"
402 " dictated by wavelet reversibility and image dimensions.");
408 ui32 total_tiles = tiles_w * tiles_h;
414 "Lossy IMF profile must have one tile.");
417 imf2kls &= (tt.
w == 1024 && tt.
h == 1024);
418 imf2kls &= (tt.
w >= 1024 && num_decomps <= 4)
419 || (tt.
w >= 2048 && num_decomps <= 5);
420 imf4kls &= (tt.
w == 1024 && tt.
h == 1024)
421 || (tt.
w == 2048 && tt.
h == 2048);
422 imf4kls &= (tt.
w >= 1024 && num_decomps <= 4)
423 || (tt.
w >= 2048 && num_decomps <= 5)
424 || (tt.
w >= 4096 && num_decomps <= 6);
425 imf8kls &= (tt.
w == 1024 && tt.
h == 1024)
426 || (tt.
w == 2048 && tt.
h == 2048)
427 || (tt.
w == 4096 && tt.
h == 4096);
428 imf8kls &= (tt.
w >= 1024 && num_decomps <= 4)
429 || (tt.
w >= 2048 && num_decomps <= 5)
430 || (tt.
w >= 4096 && num_decomps <= 6)
431 || (tt.
w >= 8192 && num_decomps <= 7);
432 if (!imf2kls && !imf4kls && !imf8kls)
434 "Number of decompositions does not match the IMF profile"
435 " dictated by wavelet reversibility and image dimensions and"
445 "In IMF profile, tile part divisions at the component level must be "
446 "employed, while at the resolution level is not allowed. "
447 "This has been corrected.");
459 "For broadcast profile, image offset (XOsiz, YOsiz) has to be 0.");
462 "For broadcast profile, tile offset (XTOsiz, YTOsiz) has to be 0.");
465 "For broadcast profile, the number of components has to be less "
467 bool test_ds1 =
true, test_ds2 =
true;
471 test_ds1 &= downsamping.
y == 1;
472 test_ds2 &= downsamping.
y == 1;
474 test_ds1 &= downsamping.
x == 1;
475 if (i == 1 || i == 2)
476 test_ds2 &= downsamping.
x == 2;
478 test_ds2 &= downsamping.
x == 1;
480 if (!test_ds1 && !test_ds2)
482 "For broadcast profile, either no component downsampling is used,"
483 " or the x-dimension of the 2nd and 3rd components is downsampled"
491 test_bd &= bit_depth >= 8 && bit_depth <= 12 && is_signed ==
false;
495 "For broadcast profile, compnent bit_depth has to be between"
496 " 8 and 12 bits inclusively, and the samples must be unsigned");
499 if (num_decomps == 0 || num_decomps > 5)
501 "For broadcast profile, number of decompositions has to be between"
502 "1 and 5 inclusively.");
506 "For broadcast profile, codeblock dimensions are restricted such"
507 " that codeblock width has to be either 32, 64, or 128.");
511 "For broadcast profile, codeblock dimensions are restricted such"
512 " that codeblock height has to be either 32, 64, or 128.");
516 for (
ui32 i = 1; i <= num_decomps; ++i)
521 "For broadcast profile, precinct sizes are restricted."
522 " Use \"-precincts {128,128},{256,256}\" at the commandline");
526 "For broadcast profile, the CPRL progression order must be used."
527 " Use \"-prog_order CPRL\".");
533 ui32 total_tiles = tiles_w * tiles_h;
535 if (total_tiles != 1 && total_tiles != 4)
537 "The broadcast profile can only have 1 or 4 tiles");
545 "In BROADCAST profile, tile part divisions at the component level "
546 "must be employed, while at the resolution level is not allowed. "
547 "This has been corrected.");
572 "For LRCP and RLCP progression orders, tilepart divisions at the "
573 "component level, means that we have a tilepart for every "
574 "resolution and component.\n");
580 "For RPCL progression, having tilepart divisions at the component "
581 "level means a tilepart for every precinct, which does not "
582 "make sense, since we can have no more than 255 tile parts. This "
583 "has been corrected by removing tilepart divisions at the component "
590 "For PCRL progression, having tilepart divisions at the component "
591 "level or the resolution level means a tile part for every "
592 "precinct, which does not make sense, since we can have no more "
593 "than 255 tile parts. This has been corrected by removing tilepart "
594 "divisions; use another progression if you want tileparts.");
600 "For CPRL progression, having tilepart divisions at the resolution "
601 "level means a tile part for every precinct, which does not "
602 "make sense, since we can have no more than 255 tile parts. This "
603 "has been corrected by removing tilepart divisions at the "
604 "resolution level.");
616 "the planar interface option cannot be used when colour "
617 "transform is employed");
628 if (file->
write(&t, 2) != 2)
629 OJPH_ERROR(0x00030022,
"Error writing to file");
632 OJPH_ERROR(0x00030023,
"Error writing to file");
635 OJPH_ERROR(0x00030024,
"Error writing to file");
638 OJPH_ERROR(0x00030025,
"Error writing to file");
641 OJPH_ERROR(0x00030026,
"Error writing to file");
643 char buf[] =
" OpenJPH Ver "
647 size_t len = strlen(buf);
652 if (file->
write(buf, len) != len)
653 OJPH_ERROR(0x00030027,
"Error writing to file");
655 if (comments != NULL) {
656 for (
ui32 i = 0; i < num_comments; ++i)
659 if (file->
write(&t, 2) != 2)
660 OJPH_ERROR(0x00030028,
"Error writing to file");
662 if (file->
write(&t, 2) != 2)
663 OJPH_ERROR(0x00030029,
"Error writing to file");
666 if (file->
write(&t, 2) != 2)
667 OJPH_ERROR(0x0003002A,
"Error writing to file");
669 OJPH_ERROR(0x0003002B,
"Error writing to file");
682 size_t num_bytes = f->
read(&new_char, 1);
685 if (new_char == 0xFF)
687 size_t num_bytes = f->
read(&new_char, 1);
692 for (
int i = 0; i < list_len; ++i)
693 if (new_char == (char_list[i] & 0xFF))
703 const char *msg,
int msg_level,
bool resilient)
707 if (file->
read(&com_len, 2) != 2)
712 OJPH_ERROR(0x00030041,
"error reading marker");
745 int received_markers = 0;
748 marker_idx =
find_marker(file, marker_list + 2, 15);
751 else if (marker_idx == 1)
754 else if (marker_idx == 2)
757 else if (marker_idx == 3)
759 cod.
read(file); received_markers |= 1;
762 if (num_qlayers != 1)
763 OJPH_ERROR(0x00030053,
"The current implementation supports "
764 "1 quality layer only. This codestream has %d quality layers",
767 else if (marker_idx == 4)
768 skip_marker(file,
"COC",
"COC is not supported yet",
770 else if (marker_idx == 5)
771 {
qcd.
read(file); received_markers |= 2; }
772 else if (marker_idx == 6)
782 else if (marker_idx == 7)
783 skip_marker(file,
"RGN",
"RGN is not supported yet",
785 else if (marker_idx == 8)
786 skip_marker(file,
"POC",
"POC is not supported yet",
788 else if (marker_idx == 9)
789 skip_marker(file,
"PPM",
"PPM is not supported yet",
791 else if (marker_idx == 10)
794 else if (marker_idx == 11)
797 else if (marker_idx == 12)
799 skip_marker(file,
"CRG",
"CRG has been ignored; CRG is related to"
800 " where the Cb and Cr colour components are co-sited or located"
801 " with respect to the Y' luma component. Perhaps, it is better"
802 " to get the indivdual components and assemble the samples"
803 " according to your needs",
805 else if (marker_idx == 13)
807 else if (marker_idx == 14)
810 OJPH_ERROR(0x00030051,
"File ended before finding a tile segment");
813 if (received_markers != 3)
814 OJPH_ERROR(0x00030052,
"markers error, COD and QCD are required");
822 ui32 skipped_res_for_recon)
826 "skipped_resolution for data %d must be equal or smaller than "
827 " skipped_resolution for reconstruction %d\n",
831 "skipped_resolution for data %d must be smaller than "
832 " the number of decomposition levels %d\n",
844 OJPH_ERROR(0x000300A3,
"Codestream resilience must be enabled before"
845 " reading file headers.\n");
865 OJPH_INFO(0x00030061,
"wrong tile index")
877 "error in tile part number, should be smaller than total"
878 " number of tile parts")
881 "error in tile part number, should be smaller than total"
882 " number of tile parts")
885 bool sod_found =
false;
894 "POC in a tile is not supported yet",
896 else if (marker_idx == 1)
898 "PPT in a tile is not supported yet",
900 else if (marker_idx == 2)
904 else if (marker_idx == 3)
907 else if (marker_idx == 4)
913 if (marker_idx == -1)
917 "File terminated early before start of data is found"
918 " for tile indexed %d and tile part %d",
922 "File terminated early before start of data is found"
923 " for tile indexed %d and tile part %d",
931 "File terminated during marker segment skipping")
934 "File terminated during marker segment skipping")
940 tile_start_location);
944 bool sod_found =
false;
954 "COD in a tile is not supported yet",
956 else if (marker_idx == 1)
958 "COC in a tile is not supported yet",
960 else if (marker_idx == 2)
962 "QCD in a tile is not supported yet",
964 else if (marker_idx == 3)
966 "QCC in a tile is not supported yet",
968 else if (marker_idx == 4)
970 "RGN in a tile is not supported yet",
972 else if (marker_idx == 5)
974 "POC in a tile is not supported yet",
976 else if (marker_idx == 6)
978 "PPT in a tile is not supported yet",
980 else if (marker_idx == 7)
984 else if (marker_idx == 8)
987 else if (marker_idx == 9)
993 if (marker_idx == -1)
997 "File terminated early before start of data is found"
998 " for tile indexed %d and tile part %d",
1002 "File terminated early before start of data is found"
1003 " for tile indexed %d and tile part %d",
1011 "File terminated during marker segment skipping")
1014 "File terminated during marker segment skipping")
1020 tile_start_location);
1028 if (marker_idx == -1)
1030 OJPH_INFO(0x00030067,
"File terminated early");
1033 else if (marker_idx == 0)
1035 else if (marker_idx == 1)
1049 size_t len = strlen(s);
1055 OJPH_ERROR(0x000300A1,
"unkownn or unsupported profile");
1074 for (
si32 i = 0; i < repeat; ++i)
1075 tiles[i].prepare_for_flush();
1078 for (
si32 i = 0; i < repeat; ++i)
1082 for (
si32 i = 0; i < repeat; ++i)
1086 OJPH_ERROR(0x00030071,
"Error writing to file");
1103 bool success =
false;
1152 bool success =
false;
1194 return lines + comp_num;
virtual size_t read(void *ptr, size_t size)=0
ui32 skipped_res_for_recon
ojph::param_siz access_siz()
void request_tlm_marker(bool needed)
line_buf * exchange(line_buf *line, ui32 &next_component)
void set_planar(int planar)
void check_imf_validity()
void restrict_input_resolution(ui32 skipped_res_for_data, ui32 skipped_res_for_recon)
mem_elastic_allocator * elastic_alloc
mem_fixed_allocator * allocator
void write_headers(outfile_base *file, const comment_exchange *comments, ui32 num_comments)
ui32 precinct_scratch_needed_bytes
void check_broadcast_validity()
void read_headers(infile_base *file)
void set_profile(const char *s)
bool employ_color_transform
void set_tilepart_divisions(ui32 value)
line_buf * pull(ui32 &comp_num)
ui32 skipped_res_for_read
static void pre_alloc(codestream *codestream, const rect &tile_rect, const rect &recon_tile_rect, ui32 &num_tileparts)
void finalize_alloc(codestream *codestream, const rect &tile_rect, const rect &recon_tile_rect, ui32 tile_idx, ui32 offset, ui32 &num_tileparts)
void parse_tile_header(const param_sot &sot, infile_base *file, const ui64 &tile_start_location)
void pre_alloc_data(size_t num_ele, ui32 pre_size)
void pre_alloc_obj(size_t num_ele)
T * post_alloc_data(size_t num_ele, ui32 pre_size)
T * post_alloc_obj(size_t num_ele)
virtual size_t write(const void *ptr, size_t size)=0
OJPH_EXPORT int get_progression_order() const
OJPH_EXPORT ui32 get_num_decompositions() const
OJPH_EXPORT size get_log_block_dims() const
OJPH_EXPORT bool is_reversible() const
OJPH_EXPORT size get_log_precinct_size(ui32 level_num) const
OJPH_EXPORT int get_num_layers() const
OJPH_EXPORT point get_image_extent() const
OJPH_EXPORT ui32 get_bit_depth(ui32 comp_num) const
OJPH_EXPORT point get_image_offset() const
OJPH_EXPORT size get_tile_size() const
OJPH_EXPORT point get_downsampling(ui32 comp_num) const
OJPH_EXPORT point get_tile_offset() const
OJPH_EXPORT bool is_signed(ui32 comp_num) const
OJPH_EXPORT ui32 get_num_components() const
static int find_marker(infile_base *f, const ui16 *char_list, int list_len)
static int skip_marker(infile_base *file, const char *marker, const char *msg, int msg_level, bool resilient)
void init_wavelet_transform_functions()
void init_colour_transform_functions()
static ui16 swap_byte(ui16 t)
const char OJPH_PN_STRING_BROADCAST[]
const char OJPH_PN_STRING_IMF[]
@ OJPH_TILEPART_RESOLUTIONS
@ OJPH_TILEPART_COMPONENTS
@ OJPH_TILEPART_NODIVSIONS
#define OJPH_INT_TO_STRING(I)
#define ojph_div_ceil(a, b)
#define OJPH_ERROR(t,...)
#define OPENJPH_VERSION_PATCH
#define OPENJPH_VERSION_MAJOR
#define OPENJPH_VERSION_MINOR
void wrap(T *buffer, size_t num_ele, ui32 pre_size)
void check_validity(const param_cod &cod, const param_qcd &qcd)
void read(infile_base *file)
bool write(outfile_base *file)
void check_validity(const param_siz &siz)
bool write(outfile_base *file)
size get_log_block_dims() const
bool is_employing_color_transform() const
void read(infile_base *file)
size get_log_precinct_size(ui32 res_num) const
ui8 get_num_decompositions() const
void read(infile_base *file, ui32 num_comps)
void check_validity(const param_siz &siz, const param_cod &cod)
bool write(outfile_base *file)
void read(infile_base *file)
void set_skipped_resolutions(ui32 skipped_resolutions)
ui32 get_recon_height(ui32 comp_num) const
bool write(outfile_base *file)
ui16 get_num_components() const
ui32 get_height(ui32 comp_num) const
void read(infile_base *file)
ui32 get_width(ui32 comp_num) const
ui32 get_recon_width(ui32 comp_num) const
ui8 get_num_tile_parts() const
ui16 get_tile_index() const
bool read(infile_base *file, bool resilient)
ui8 get_tile_part_index() const
bool write(outfile_base *file)
void init(ui32 num_pairs, Ttlm_Ptlm_pair *store)