48 #include "../transform/ojph_colour.h"
49 #include "../transform/ojph_transform.h"
50 #include "../coding/ojph_block_decoder.h"
51 #include "../coding/ojph_block_encoder.h"
131 ui32 skipped_res_for_recon)
134 skipped_res_for_recon);
185 return (
ui16)((t << 8) | (t >> 8));
198 : precinct_scratch(NULL), allocator(NULL), elastic_alloc(NULL)
251 OJPH_ERROR(0x00030011,
"number of tiles cannot exceed 65535");
257 rect tile_rect, recon_tile_rect;
259 for (index.y = 0; index.y <
num_tiles.
h; ++index.y)
273 - recon_tile_rect.
org.
y;
275 for (index.x = 0; index.x <
num_tiles.
w; ++index.x)
289 - recon_tile_rect.
org.
x;
328 for (
ui32 r = 0; r <= num_decomps; ++r)
331 log_PP.
w -= (r ? 1 : 0);
332 log_PP.
h -= (r ? 1 : 0);
337 max_ratio = 1 << max_ratio;
346 4 * ((max_ratio * max_ratio * 4 + 2) / 3);
364 rect tile_rect, recon_tile_rect;
367 for (index.y = 0; index.y <
num_tiles.
h; ++index.y)
381 - recon_tile_rect.
org.
y;
384 for (index.x = 0; index.x <
num_tiles.
w; ++index.x)
398 - recon_tile_rect.
org.
x;
403 offset += recon_tile_rect.
siz.
w;
458 bool imf2k = !reversible, imf4k = !reversible, imf8k = !reversible;
459 bool imf2kls = reversible, imf4kls = reversible, imf8kls = reversible;
464 if (ext.
x <= 2048 && ext.
y <= 1556)
466 if (ext.
x <= 4096 && ext.
y <= 3112)
468 if (ext.
x <= 8192 && ext.
y <= 6224)
471 if (!imf2kls && !imf4kls && !imf8kls)
473 "Image dimensions do not meet any of the lossless IMF profiles");
478 if (ext.
x <= 2048 && ext.
y <= 1556)
480 if (ext.
x <= 4096 && ext.
y <= 3112)
482 if (ext.
x <= 8192 && ext.
y <= 6224)
485 if (!imf2k && !imf4k && !imf8k)
487 "Image dimensions do not meet any of the lossy IMF profiles");
493 "For IMF profile, image offset (XOsiz, YOsiz) has to be 0.");
496 "For IMF profile, tile offset (XTOsiz, YTOsiz) has to be 0.");
499 "For IMF profile, the number of components has to be less "
501 bool test_ds1 =
true, test_ds2 =
true;
505 test_ds1 &= downsamping.
y == 1;
506 test_ds2 &= downsamping.
y == 1;
508 test_ds1 &= downsamping.
x == 1;
509 if (i == 1 || i == 2)
510 test_ds2 &= downsamping.
x == 2;
512 test_ds2 &= downsamping.
x == 1;
514 if (!test_ds1 && !test_ds2)
516 "For IMF profile, either no component downsampling is used,"
517 " or the x-dimension of the 2nd and 3rd components is downsampled"
525 test_bd &= bit_depth >= 8 && bit_depth <= 16 && is_signed ==
false;
529 "For IMF profile, compnent bit_depth has to be between"
530 " 8 and 16 bits inclusively, and the samples must be unsigned");
534 "For IMF profile, codeblock dimensions are restricted."
535 " Use \"-block_size {32,32}\" at the commandline");
540 for (
ui32 i = 1; i <= num_decomps; ++i)
545 "For IMF profile, precinct sizes are restricted."
546 " Use \"-precincts {128,128},{256,256}\" at the commandline");
550 "For IMF profile, the CPRL progression order must be used."
551 " Use \"-prog_order CPRL\".");
553 imf2k &= num_decomps <= 5;
554 imf2kls &= num_decomps <= 5;
555 imf4k &= num_decomps <= 6;
556 imf4kls &= num_decomps <= 6;
557 imf8k &= num_decomps <= 7;
558 imf8kls &= num_decomps <= 7;
560 if (num_decomps == 0 ||
561 (!imf2k && !imf4k && !imf8k && !imf2kls && !imf4kls && !imf8kls))
563 "Number of decompositions does not match the IMF profile"
564 " dictated by wavelet reversibility and image dimensions.");
570 ui32 total_tiles = tiles_w * tiles_h;
576 "Lossy IMF profile must have one tile.");
579 imf2kls &= (tt.
w == 1024 && tt.
h == 1024);
580 imf2kls &= (tt.
w >= 1024 && num_decomps <= 4)
581 || (tt.
w >= 2048 && num_decomps <= 5);
582 imf4kls &= (tt.
w == 1024 && tt.
h == 1024)
583 || (tt.
w == 2048 && tt.
h == 2048);
584 imf4kls &= (tt.
w >= 1024 && num_decomps <= 4)
585 || (tt.
w >= 2048 && num_decomps <= 5)
586 || (tt.
w >= 4096 && num_decomps <= 6);
587 imf8kls &= (tt.
w == 1024 && tt.
h == 1024)
588 || (tt.
w == 2048 && tt.
h == 2048)
589 || (tt.
w == 4096 && tt.
h == 4096);
590 imf8kls &= (tt.
w >= 1024 && num_decomps <= 4)
591 || (tt.
w >= 2048 && num_decomps <= 5)
592 || (tt.
w >= 4096 && num_decomps <= 6)
593 || (tt.
w >= 8192 && num_decomps <= 7);
594 if (!imf2kls && !imf4kls && !imf8kls)
596 "Number of decompositions does not match the IMF profile"
597 " dictated by wavelet reversibility and image dimensions and"
611 "For broadcast profile, image offset (XOsiz, YOsiz) has to be 0.");
614 "For broadcast profile, tile offset (XTOsiz, YTOsiz) has to be 0.");
617 "For broadcast profile, the number of components has to be less "
619 bool test_ds1 =
true, test_ds2 =
true;
623 test_ds1 &= downsamping.
y == 1;
624 test_ds2 &= downsamping.
y == 1;
626 test_ds1 &= downsamping.
x == 1;
627 if (i == 1 || i == 2)
628 test_ds2 &= downsamping.
x == 2;
630 test_ds2 &= downsamping.
x == 1;
632 if (!test_ds1 && !test_ds2)
634 "For broadcast profile, either no component downsampling is used,"
635 " or the x-dimension of the 2nd and 3rd components is downsampled"
643 test_bd &= bit_depth >= 8 && bit_depth <= 12 && is_signed ==
false;
647 "For broadcast profile, compnent bit_depth has to be between"
648 " 8 and 12 bits inclusively, and the samples must be unsigned");
651 if (num_decomps == 0 || num_decomps > 5)
653 "For broadcast profile, number of decompositions has to be between"
654 "1 and 5 inclusively.");
658 "For broadcast profile, codeblock dimensions are restricted such"
659 " that codeblock width has to be either 32, 64, or 128.");
663 "For broadcast profile, codeblock dimensions are restricted such"
664 " that codeblock height has to be either 32, 64, or 128.");
668 for (
ui32 i = 1; i <= num_decomps; ++i)
673 "For broadcast profile, precinct sizes are restricted."
674 " Use \"-precincts {128,128},{256,256}\" at the commandline");
678 "For broadcast profile, the CPRL progression order must be used."
679 " Use \"-prog_order CPRL\".");
685 ui32 total_tiles = tiles_w * tiles_h;
687 if (total_tiles != 1 && total_tiles != 4)
689 "The broadcast profile can only have 1 or 4 tiles");
714 "the planar interface option cannot be used when colour "
715 "transform is employed");
726 if (file->
write(&t, 2) != 2)
727 OJPH_ERROR(0x00030022,
"Error writing to file");
730 OJPH_ERROR(0x00030023,
"Error writing to file");
733 OJPH_ERROR(0x00030024,
"Error writing to file");
736 OJPH_ERROR(0x00030025,
"Error writing to file");
739 OJPH_ERROR(0x00030026,
"Error writing to file");
741 char buf[] =
" OpenJPH Ver "
745 size_t len = strlen(buf);
750 if (file->
write(buf, len) != len)
751 OJPH_ERROR(0x00030027,
"Error writing to file");
762 size_t num_bytes = f->
read(&new_char, 1);
765 if (new_char == 0xFF)
767 size_t num_bytes = f->
read(&new_char, 1);
772 for (
int i = 0; i < list_len; ++i)
773 if (new_char == (char_list[i] & 0xFF))
783 const char *msg,
int msg_level,
bool resilient)
787 if (file->
read(&com_len, 2) != 2)
792 OJPH_ERROR(0x00030041,
"error reading marker");
825 int received_markers = 0;
828 marker_idx =
find_marker(file, marker_list + 2, 15);
831 else if (marker_idx == 1)
834 else if (marker_idx == 2)
837 else if (marker_idx == 3)
838 {
cod.
read(file); received_markers |= 1; }
839 else if (marker_idx == 4)
840 skip_marker(file,
"COC",
"COC is not supported yet",
842 else if (marker_idx == 5)
843 {
qcd.
read(file); received_markers |= 2; }
844 else if (marker_idx == 6)
854 else if (marker_idx == 7)
855 skip_marker(file,
"RGN",
"RGN is not supported yet",
857 else if (marker_idx == 8)
858 skip_marker(file,
"POC",
"POC is not supported yet",
860 else if (marker_idx == 9)
861 skip_marker(file,
"PPM",
"PPM is not supported yet",
863 else if (marker_idx == 10)
866 else if (marker_idx == 11)
869 else if (marker_idx == 12)
871 skip_marker(file,
"CRG",
"CRG has been ignored; CRG is related to"
872 " where the Cb and Cr colour components are co-sited or located"
873 " with respect to the Y' luma component. Perhaps, it is better"
874 " to get the indivdual components and assemble the samples"
875 " according to your needs",
877 else if (marker_idx == 13)
879 else if (marker_idx == 14)
882 OJPH_ERROR(0x00030051,
"File ended before finding a tile segment");
885 if (received_markers != 3)
886 OJPH_ERROR(0x00030052,
"markers error, COD and QCD are required");
894 ui32 skipped_res_for_recon)
898 "skipped_resolution for data %d must be equal or smaller than "
899 " skipped_resolution for reconstruction %d\n",
903 "skipped_resolution for data %d must be smaller than "
904 " the number of decomposition levels %d\n",
916 OJPH_ERROR(0x000300A3,
"Codestream resilience must be enabled before"
917 " reading file headers.\n");
937 OJPH_INFO(0x00030061,
"wrong tile index")
949 "error in tile part number, should be smaller than total"
950 " number of tile parts")
953 "error in tile part number, should be smaller than total"
954 " number of tile parts")
957 bool sod_found =
false;
966 "POC in a tile is not supported yet",
968 else if (marker_idx == 1)
970 "PPT in a tile is not supported yet",
972 else if (marker_idx == 2)
976 else if (marker_idx == 3)
979 else if (marker_idx == 4)
985 if (marker_idx == -1)
989 "File terminated early before start of data is found"
990 " for tile indexed %d and tile part %d",
994 "File terminated early before start of data is found"
995 " for tile indexed %d and tile part %d",
1003 "File terminated during marker segment skipping")
1006 "File terminated during marker segment skipping")
1012 tile_start_location);
1016 bool sod_found =
false;
1024 if (marker_idx == 0)
1026 "COD in a tile is not supported yet",
1028 else if (marker_idx == 1)
1030 "COC in a tile is not supported yet",
1032 else if (marker_idx == 2)
1034 "QCD in a tile is not supported yet",
1036 else if (marker_idx == 3)
1038 "QCC in a tile is not supported yet",
1040 else if (marker_idx == 4)
1042 "RGN in a tile is not supported yet",
1044 else if (marker_idx == 5)
1046 "POC in a tile is not supported yet",
1048 else if (marker_idx == 6)
1050 "PPT in a tile is not supported yet",
1052 else if (marker_idx == 7)
1056 else if (marker_idx == 8)
1059 else if (marker_idx == 9)
1065 if (marker_idx == -1)
1069 "File terminated early before start of data is found"
1070 " for tile indexed %d and tile part %d",
1074 "File terminated early before start of data is found"
1075 " for tile indexed %d and tile part %d",
1083 "File terminated during marker segment skipping")
1086 "File terminated during marker segment skipping")
1092 tile_start_location);
1100 if (marker_idx == -1)
1102 OJPH_INFO(0x00030067,
"File terminated early");
1105 else if (marker_idx == 0)
1107 else if (marker_idx == 1)
1121 size_t len = strlen(s);
1127 OJPH_ERROR(0x000300A1,
"unkownn or unsupported profile");
1134 for (
si32 i = 0; i < repeat; ++i)
1135 tiles[i].prepare_for_flush();
1138 for (
si32 i = 0; i < repeat; ++i)
1142 for (
si32 i = 0; i < repeat; ++i)
1146 OJPH_ERROR(0x00030071,
"Error writing to file");
1163 bool success =
false;
1212 bool success =
false;
1267 const rect& recon_tile_rect)
1312 comp_rect.
org.
x = tcx0;
1313 comp_rect.
org.
y = tcy0;
1314 comp_rect.
siz.
w = tcx1 - tcx0;
1315 comp_rect.
siz.
h = tcy1 - tcy0;
1317 rect recon_comp_rect;
1318 recon_comp_rect.
org.
x = recon_tcx0;
1319 recon_comp_rect.
org.
y = recon_tcy0;
1320 recon_comp_rect.
siz.
w = recon_tcx1 - recon_tcx0;
1321 recon_comp_rect.
siz.
h = recon_tcy1 - recon_tcy0;
1331 for (
int i = 0; i < 3; ++i)
1338 const rect& recon_tile_rect,
1421 for (
int i = 0; i < 3; ++i)
1450 int shift = 1 << (
num_bits[comp_num] - 1);
1454 memcpy(dp, sp, comp_width *
sizeof(
si32));
1460 float mul = 1.0f / (float)(1<<
num_bits[comp_num]);
1462 float *dp = tc->
f32;
1475 int shift = 1 << (
num_bits[comp_num] - 1);
1479 memcpy(dp, sp, comp_width *
sizeof(
si32));
1485 comps[0].get_line()->i32,
1486 comps[1].get_line()->i32,
1487 comps[2].get_line()->i32, comp_width);
1495 float mul = 1.0f / (float)(1<<
num_bits[comp_num]);
1505 comps[0].get_line()->f32,
1506 comps[1].get_line()->f32,
1507 comps[2].get_line()->f32, comp_width);
1533 int shift = 1 << (
num_bits[comp_num] - 1);
1534 const si32 *sp = src_line->
i32;
1537 memcpy(dp, sp, comp_width *
sizeof(
si32));
1543 float mul = (float)(1 <<
num_bits[comp_num]);
1544 const float *sp = src_line->
f32;
1561 lines[2].i32, comp_width);
1565 lines[2].f32, comp_width);
1569 int shift = 1 << (
num_bits[comp_num] - 1);
1577 memcpy(dp, sp, comp_width *
sizeof(
si32));
1583 float mul = (float)(1 <<
num_bits[comp_num]);
1632 ui32 max_decompositions = 0;
1634 max_decompositions =
ojph_max(max_decompositions,
1635 comps[c].get_num_decompositions());
1641 OJPH_ERROR(0x00030081,
"Error writing to file");
1645 if (!file->
write(&t, 2))
1646 OJPH_ERROR(0x00030082,
"Error writing to file");
1653 for (
ui32 r = 0; r <= max_decompositions; ++r)
1655 comps[c].write_precincts(r, file);
1659 for (
ui32 r = 0; r <= max_decompositions; ++r)
1665 point smallest(INT_MAX, INT_MAX), cur;
1668 if (!
comps[c].get_top_left_precinct(r, cur))
1673 if (cur.
y < smallest.y)
1674 { smallest = cur; comp_num = c; }
1675 else if (cur.
y == smallest.y && cur.
x < smallest.x)
1676 { smallest = cur; comp_num = c; }
1692 point smallest(INT_MAX, INT_MAX), cur;
1697 if (!
comps[c].get_top_left_precinct(r, cur))
1702 if (cur.
y < smallest.y)
1703 { smallest = cur; comp_num = c; res_num = r; }
1704 else if (cur.
y == smallest.y && cur.
x < smallest.x)
1705 { smallest = cur; comp_num = c; res_num = r; }
1706 else if (cur.
y == smallest.y && cur.
x == smallest.x &&
1708 { smallest = cur; comp_num = c; res_num = r; }
1709 else if (cur.
y == smallest.y && cur.
x == smallest.x &&
1710 c == comp_num && r < res_num)
1711 { smallest = cur; comp_num = c; res_num = r; }
1728 OJPH_ERROR(0x00030083,
"Error writing to file");
1732 if (!file->
write(&t, 2))
1733 OJPH_ERROR(0x00030084,
"Error writing to file");
1740 point smallest(INT_MAX, INT_MAX), cur;
1741 for (
ui32 r = 0; r <= max_decompositions; ++r)
1743 if (!
comps[c].get_top_left_precinct(r, cur))
1748 if (cur.
y < smallest.y)
1749 { smallest = cur; res_num = r; }
1750 else if (cur.
y == smallest.y && cur.
x < smallest.x)
1751 { smallest = cur; res_num = r; }
1767 const ui64& tile_start_location)
1772 OJPH_INFO(0x00030091,
"wrong tile part index")
1774 OJPH_ERROR(0x00030091,
"wrong tile part index")
1782 data_left -= (
ui32)((
ui64)file->
tell() - tile_start_location);
1787 ui32 max_decompositions = 0;
1789 max_decompositions =
ojph_max(max_decompositions,
1790 comps[c].get_num_decompositions());
1798 for (
ui32 r = 0; r <= max_decompositions; ++r)
1806 for (
ui32 r = 0; r <= max_decompositions; ++r)
1812 point smallest(INT_MAX, INT_MAX), cur;
1815 if (!
comps[c].get_top_left_precinct(r, cur))
1820 if (cur.
y < smallest.y)
1821 { smallest = cur; comp_num = c; }
1822 else if (cur.
y == smallest.y && cur.
x < smallest.x)
1823 { smallest = cur; comp_num = c; }
1825 if (found ==
true && data_left > 0)
1839 point smallest(INT_MAX, INT_MAX), cur;
1844 if (!
comps[c].get_top_left_precinct(r, cur))
1849 if (cur.
y < smallest.y)
1850 { smallest = cur; comp_num = c; res_num = r; }
1851 else if (cur.
y == smallest.y && cur.
x < smallest.x)
1852 { smallest = cur; comp_num = c; res_num = r; }
1853 else if (cur.
y == smallest.y && cur.
x == smallest.x &&
1855 { smallest = cur; comp_num = c; res_num = r; }
1856 else if (cur.
y == smallest.y && cur.
x == smallest.x &&
1857 c == comp_num && r < res_num)
1858 { smallest = cur; comp_num = c; res_num = r; }
1861 if (found ==
true && data_left > 0)
1875 point smallest(INT_MAX, INT_MAX), cur;
1876 for (
ui32 r = 0; r <= max_decompositions; ++r)
1878 if (!
comps[c].get_top_left_precinct(r, cur))
1883 if (cur.
y < smallest.y)
1884 { smallest = cur; res_num = r; }
1885 else if (cur.
y == smallest.y && cur.
x < smallest.x)
1886 { smallest = cur; res_num = r; }
1888 if (found ==
true && data_left > 0)
1899 catch (
const char *
error)
1919 const rect& recon_comp_rect)
1933 ui32 comp_num,
const rect& comp_rect,
1934 const rect& recon_comp_rect)
1981 while (res_num > 0 && r != NULL)
1996 while (res_num > 0 && r != NULL)
2013 while (res_num > 0 && r != NULL)
2029 while (res_num > 0 && r != NULL)
2046 while (res_num > 0 && r != NULL)
2069 assert(line1->
size == line2->
size &&
2087 assert(line1->
size == line2->
size &&
2108 const rect& recon_res_rect,
ui32 res_num)
2126 next_res_rect.
org.
x = trx0;
2127 next_res_rect.
org.
y = try0;
2128 next_res_rect.
siz.
w = trx1 - trx0;
2129 next_res_rect.
siz.
h = try1 - try0;
2143 for (
ui32 i = 1; i < 4; ++i)
2145 ui32 tbx0 = (trx0 - (i&1) + 1) >> 1;
2146 ui32 tbx1 = (trx1 - (i&1) + 1) >> 1;
2147 ui32 tby0 = (try0 - (i>>1) + 1) >> 1;
2148 ui32 tby1 = (try1 - (i>>1) + 1) >> 1;
2151 band_rect.
org.
x = tbx0;
2152 band_rect.
org.
y = tby0;
2153 band_rect.
siz.
w = tbx1 - tbx0;
2154 band_rect.
siz.
h = tby1 - tby0;
2164 if (trx0 != trx1 && try0 != try1)
2188 const rect& res_rect,
2189 const rect& recon_res_rect,
2191 point comp_downsamp,
2220 next_res_rect.
org.
x = trx0;
2221 next_res_rect.
org.
y = try0;
2222 next_res_rect.
siz.
w = trx1 - trx0;
2223 next_res_rect.
siz.
h = try1 - try0;
2241 for (
ui32 i = 1; i < 4; ++i)
2243 ui32 tbx0 = (trx0 - (i&1) + 1) >> 1;
2244 ui32 tbx1 = (trx1 - (i&1) + 1) >> 1;
2245 ui32 tby0 = (try0 - (i>>1) + 1) >> 1;
2246 ui32 tby1 = (try1 - (i>>1) + 1) >> 1;
2249 band_rect.
org.
x = tbx0;
2250 band_rect.
org.
y = tby0;
2251 band_rect.
siz.
w = tbx1 - tbx0;
2252 band_rect.
siz.
h = tby1 - tby0;
2265 if (trx0 != trx1 && try0 != try1)
2291 point t(proj_factor.
x * ppx0, proj_factor.
y * ppy0);
2292 t.x = t.x > tile_top_left.
x ? t.x : tile_top_left.
x;
2293 t.y = t.y > tile_top_left.
y ? t.y : tile_top_left.
y;
2306 for (
int i = 1; i < 4; ++i)
2320 for (
ui32 i = 1; i <= max_num_levels; ++i, val >>= 2)
2432 for (
ui32 i = width; i > 0; --i)
2456 lines + 1, 0, width);
2459 lines + 2, 1, width);
2462 lines + 3, 2, width);
2465 lines + 4, 3, width);
2498 lines + 1, 2, width);
2501 lines + 2, 3, width);
2534 lines + 1, 1, width);
2537 lines + 2, 2, width);
2540 lines + 3, 3, width);
2546 lines + 1, 3, width);
2677 for (
ui32 i = width; i > 0; --i)
2718 lines + 1, 7, width);
2722 lines + 2, 6, width);
2726 lines + 3, 5, width);
2730 lines + 4, 4, width);
2755 for (
ui32 i = width; i > 0; --i)
2769 ui32 used_bytes = 0;
2774 for (
si32 i = 0; i < repeat; ++i)
2879 assert(cur_coded_list == NULL);
2881 bbp->
ccl = cur_coded_list;
2912 cur_coded_list = cur_coded_list->
next_list;
2925 for (
int i = num_bits - 1; i >= 0; --i)
2926 bb_put_bit(bbp, data >> i, elastic, cur_coded_list, ph_bytes);
2965 levs[i] = buf + lev_idx[i];
2981 return levs[lev] + (x + y * ((
width + (1 << lev) - 1) >> lev));
2992 return t + (x & (x - 1) ? 1 : 0);
3005 int num_skipped_subbands = 0;
3006 for (
int s = sst; s < send; ++s)
3011 ui32 num_levels = 1 +
3015 tag_tree inc_tag, inc_tag_flags, mmsb_tag, mmsb_tag_flags;
3018 lev_idx, num_levels,
cb_idxs[s].siz, 0);
3020 lev_idx, num_levels,
cb_idxs[s].siz, 255);
3021 mmsb_tag_flags.
init(
scratch + (tag_tree_size<<1) + tag_tree_size,
3022 lev_idx, num_levels,
cb_idxs[s].siz, 0);
3036 for (
ui32 lev = 1; lev < num_levels; ++lev)
3040 for (
ui32 y = 0; y < height; ++y)
3042 for (
ui32 x = 0; x < width; ++x)
3046 *inc_tag.
get((x<<1) + 1, y<<1, lev-1));
3047 t2 =
ojph_min(*inc_tag.
get(x<<1, (y<<1) + 1, lev-1),
3048 *inc_tag.
get((x<<1) + 1, (y<<1) + 1, lev-1));
3050 *inc_tag_flags.
get(x, y, lev) = 0;
3052 *mmsb_tag.
get((x<<1) + 1, y<<1, lev-1));
3053 t2 =
ojph_min(*mmsb_tag.
get(x<<1, (y<<1) + 1, lev-1),
3054 *mmsb_tag.
get((x<<1) + 1, (y<<1) + 1, lev-1));
3056 *mmsb_tag_flags.
get(x, y, lev) = 0;
3060 *inc_tag.
get(0,0,num_levels) = 0;
3061 *inc_tag_flags.
get(0,0,num_levels) = 0;
3062 *mmsb_tag.
get(0,0,num_levels) = 0;
3063 *mmsb_tag_flags.
get(0,0,num_levels) = 0;
3064 if (*inc_tag.
get(0, 0, num_levels-1) != 0)
3067 bb_put_bits(&bb, 0, 1, elastic, cur_coded_list, ph_bytes);
3069 ++num_skipped_subbands;
3075 bb_init(&bb, elastic, cur_coded_list);
3076 coded = cur_coded_list;
3078 bb_put_bit(&bb, 1, elastic, cur_coded_list, ph_bytes);
3082 bb_put_bits(&bb, 0, num_skipped_subbands, elastic, cur_coded_list,
3084 num_skipped_subbands = 0;
3089 for (
ui32 y = 0; y < height; ++y)
3093 for (
ui32 x = 0; x < width; ++x, ++cp)
3096 for (
ui32 cur_lev = num_levels; cur_lev > 0; --cur_lev)
3098 ui32 levm1 = cur_lev - 1;
3100 if (*inc_tag_flags.
get(x>>levm1, y>>levm1, levm1) == 0)
3102 ui32 skipped = *inc_tag.
get(x>>levm1, y>>levm1, levm1);
3103 skipped -= *inc_tag.
get(x>>cur_lev, y>>cur_lev, cur_lev);
3104 assert(skipped <= 1);
3106 elastic, cur_coded_list, ph_bytes);
3107 *inc_tag_flags.
get(x>>levm1, y>>levm1, levm1) = 1;
3109 if (*inc_tag.
get(x>>levm1, y>>levm1, levm1) > 0)
3117 for (
ui32 cur_lev = num_levels; cur_lev > 0; --cur_lev)
3119 ui32 levm1 = cur_lev - 1;
3121 if (*mmsb_tag_flags.
get(x>>levm1, y>>levm1, levm1) == 0)
3123 int num_zeros = *mmsb_tag.
get(x>>levm1, y>>levm1, levm1);
3124 num_zeros -= *mmsb_tag.
get(x>>cur_lev, y>>cur_lev, cur_lev);
3126 elastic, cur_coded_list, ph_bytes);
3127 *mmsb_tag_flags.
get(x>>levm1, y>>levm1, levm1) = 1;
3135 bb_put_bits(&bb, 12, 4, elastic, cur_coded_list, ph_bytes);
3138 bb_put_bits(&bb, 2, 2, elastic, cur_coded_list, ph_bytes);
3141 bb_put_bits(&bb, 0, 1, elastic, cur_coded_list, ph_bytes);
3154 int bits =
ojph_max(bits1, bits2 - extra_bit) - 3;
3157 elastic, cur_coded_list, ph_bytes);
3160 elastic, cur_coded_list, ph_bytes);
3163 elastic, cur_coded_list, ph_bytes);
3176 return coded ? cb_bytes + ph_bytes : 1;
3195 for (
int s = sst; s < send; ++s)
3200 for (
ui32 y = 0; y < height; ++y)
3204 for (
ui32 x = 0; x < width; ++x, ++cp)
3220 file->
write(&buf, 1);
3253 throw "error reading from file";
3284 assert(num_bits <= 32);
3294 num_bits -= tx_bits;
3295 bits |= (bbp->
tmp >> bbp->
avail_bits) & ((1 << tx_bits) - 1);
3312 if (num_bytes > bytes_read)
3314 0, num_bytes - bytes_read);
3316 return bytes_read == bytes;
3326 if (bbp->
file->
read(marker, 2) != 2)
3327 throw "error reading from file";
3329 if ((
int)marker[0] != (
EPH >> 8) || (
int)marker[1] != (
EPH & 0xFF))
3330 throw "should find EPH, but found something else";
3341 assert(bbp->
unstuff ==
false);
3356 if (bbp->
file->
read(marker, 2) != 2)
3357 throw "error reading from file";
3358 if ((
int)marker[0] == (
SOP >> 8) && (
int)marker[1] == (
SOP & 0xFF))
3364 if (bbp->
file->
read(&com_len, 2) != 2)
3365 throw "error reading from file";
3368 throw "something is wrong with SOP length";
3372 throw "error seeking file";
3376 throw "precinct truncated early";
3383 throw "error seeking file";
3397 assert(data_left > 0);
3399 bb_init(&bb, data_left, file);
3405 bool empty_packet =
true;
3406 for (
int s = sst; s < send; ++s)
3417 empty_packet =
false;
3420 ui32 num_levels = 1 +
3424 tag_tree inc_tag, inc_tag_flags, mmsb_tag, mmsb_tag_flags;
3426 *inc_tag.
get(0, 0, num_levels) = 0;
3427 inc_tag_flags.
init(
scratch + tag_tree_size, lev_idx, num_levels,
3429 *inc_tag_flags.
get(0, 0, num_levels) = 0;
3430 mmsb_tag.
init(
scratch + (tag_tree_size<<1), lev_idx, num_levels,
3432 *mmsb_tag.
get(0, 0, num_levels) = 0;
3433 mmsb_tag_flags.
init(
scratch + (tag_tree_size<<1) + tag_tree_size,
3434 lev_idx, num_levels,
cb_idxs[s].siz, 0);
3435 *mmsb_tag_flags.
get(0, 0, num_levels) = 0;
3441 for (
ui32 y = 0; y < height; ++y)
3445 for (
ui32 x = 0; x < width; ++x, ++cp)
3448 bool empty_cb =
false;
3449 for (
ui32 cl = num_levels; cl > 0; --cl)
3451 ui32 cur_lev = cl - 1;
3452 empty_cb = *inc_tag.
get(x>>cur_lev, y>>cur_lev, cur_lev) == 1;
3456 if (*inc_tag_flags.
get(x>>cur_lev, y>>cur_lev, cur_lev) == 0)
3460 { data_left = 0;
throw "error reading from file p1"; }
3461 empty_cb = (bit == 0);
3462 *inc_tag.
get(x>>cur_lev, y>>cur_lev, cur_lev) = (
ui8)(1 - bit);
3463 *inc_tag_flags.
get(x>>cur_lev, y>>cur_lev, cur_lev) = 1;
3474 for (
ui32 levp1 = num_levels; levp1 > 0; --levp1)
3476 ui32 cur_lev = levp1 - 1;
3477 mmsbs = *mmsb_tag.
get(x>>levp1, y>>levp1, levp1);
3479 if (*mmsb_tag_flags.
get(x>>cur_lev, y>>cur_lev, cur_lev) == 0)
3485 { data_left = 0;
throw "error reading from file p2"; }
3488 *mmsb_tag.
get(x>>cur_lev, y>>cur_lev, cur_lev) = (
ui8)mmsbs;
3489 *mmsb_tag_flags.
get(x>>cur_lev, y>>cur_lev, cur_lev) = 1;
3493 if (mmsbs > cp->
Kmax)
3494 throw "error in parsing a tile header; "
3495 "missing msbs are larger or equal to Kmax. The most likely "
3496 "cause is a corruption in the bitstream.";
3500 ui32 bit, num_passes = 1;
3502 { data_left = 0;
throw "error reading from file p3"; }
3507 { data_left = 0;
throw "error reading from file p4"; }
3511 { data_left = 0;
throw "error reading from file p5"; }
3512 num_passes = 3 + bit;
3516 { data_left = 0;
throw "error reading from file p6"; }
3517 num_passes = 6 + bit;
3521 { data_left = 0;
throw "error reading from file p7"; }
3522 num_passes = 37 + bit;
3537 { data_left = 0;
throw "error reading from file p8"; }
3542 { data_left = 0;
throw "error reading from file p9"; }
3546 if (
bb_read_bits(&bb, bits1 + extra_bit, bit) ==
false)
3547 { data_left = 0;
throw "error reading from file p10"; }
3555 for (
int s = sst; s < send; ++s)
3560 for (
ui32 y = 0; y < height; ++y)
3564 for (
ui32 x = 0; x < width; ++x, ++cp)
3579 assert(bytes_read == t || bb.
bytes_left == 0);
3629 if (tbx0 != tbx1 && tby0 != tby1)
3656 const rect &band_rect,
3686 d /= (float)(1u << (31 - this->
K_max));
3697 if (tbx0 != tbx1 && tby0 != tby1)
3719 cb_size.
h =
ojph_min(tby1, y_lower_bound + nominal.
h) - tby0;
3721 int line_offset = 0;
3725 ui32 cbx1 =
ojph_min(tbx1, x_lower_bound + (i + 1) * nominal.
w);
3726 cb_size.
w = cbx1 - cbx0;
3729 line_offset += cb_size.
w;
3756 ui32 pcx0, pcx1, pcy0, pcy1, shift = (
band_num != 0 ? 1 : 0);
3757 ui32 yb, xb, coly = 0, colx = 0;
3758 for (
ui32 y = 0; y < num_precincts.
h; ++y)
3762 pcy0 = (pcy0 - (
band_num >> 1) + (1<<shift) - 1) >> shift;
3763 pcy1 = (pcy1 - (
band_num >> 1) + (1<<shift) - 1) >> shift;
3765 precinct *p = precincts + y * num_precincts.
w;
3770 for (
ui32 x = 0; x < num_precincts.
w; ++x, ++p)
3774 pcx0 = (pcx0 - (
band_num & 1) + (1<<shift) - 1) >> shift;
3775 pcx1 = (pcx1 - (
band_num & 1) + (1<<shift) - 1) >> shift;
3812 si32 val = *sp >= 0 ? *sp : -*sp;
3813 si32 sign = *sp >= 0 ? 0 : (int)0x80000000;
3814 *sp++ = sign | (val << shift);
3825 si32 val = t >= 0 ? t : -t;
3826 si32 sign = t >= 0 ? 0 : (int)0x80000000;
3855 cb_size.
h = cby1 -
ojph_max(tby0, cby0);
3860 ui32 cbx1 =
ojph_min(tbx1, x_lower_bound + (i + 1) * nominal.
w);
3861 cb_size.
w = cbx1 - cbx0;
3892 cb_size.
h = cby1 - cby0;
3897 ui32 cbx1 =
ojph_min(tbx1, x_lower_bound + (i + 1) * nominal.
w);
3898 cb_size.
w = cbx1 - cbx0;
3920 si32 val = (*sp & 0x7FFFFFFF) >> shift;
3921 *sp = ((
ui32)*sp & 0x80000000) ? -val : val;
3931 float val = (float)(*sp & 0x7FFFFFFF) *
delta;
3932 *dp++ = ((
ui32)*sp & 0x80000000) ? -val : val;
3950 const size& nominal)
3961 const size& cb_size,
3963 ui32 K_max,
int line_offset)
3967 this->
stride = (nominal.
w + 3) & 0xFFFFFFFC;
3976 this->K_max =
K_max;
3993 tmax =
ojph_max(tmax, 0x7FFFFFFF & t);
4041 if (result ==
false)
4046 OJPH_ERROR(0x000300A1,
"Error decoding a codeblock\n");
OJPH_EXPORT param_siz access_siz()
OJPH_EXPORT param_cod access_cod()
OJPH_EXPORT void restrict_input_resolution(ui32 skipped_res_for_data, ui32 skipped_res_for_recon)
local::codestream * state
OJPH_EXPORT void set_planar(bool planar)
OJPH_EXPORT ~codestream()
OJPH_EXPORT void enable_resilience()
OJPH_EXPORT line_buf * exchange(line_buf *line, ui32 &next_component)
OJPH_EXPORT void set_profile(const char *s)
OJPH_EXPORT void write_headers(outfile_base *file)
OJPH_EXPORT param_qcd access_qcd()
OJPH_EXPORT void read_headers(infile_base *file)
OJPH_EXPORT void create()
OJPH_EXPORT bool is_planar() const
OJPH_EXPORT line_buf * pull(ui32 &comp_num)
virtual size_t read(void *ptr, size_t size)=0
static void pre_alloc(codestream *codestream, const size &nominal)
coded_cb_header * coded_cb
void push(line_buf *line)
void encode(mem_elastic_allocator *elastic)
void recreate(const size &cb_size, coded_cb_header *coded_cb)
void finalize_alloc(codestream *codestream, subband *parent, const size &nominal, const size &cb_size, coded_cb_header *coded_cb, ui32 K_max, int tbx0)
void pull_line(line_buf *line)
ui8 * get_precinct_scratch()
ui32 skipped_res_for_recon
ojph::param_siz access_siz()
mem_elastic_allocator * get_elastic_alloc()
ui32 get_skipped_res_for_read()
line_buf * exchange(line_buf *line, ui32 &next_component)
void set_planar(int planar)
void check_imf_validity()
const param_siz * get_siz()
void restrict_input_resolution(ui32 skipped_res_for_data, ui32 skipped_res_for_recon)
mem_elastic_allocator * elastic_alloc
ojph::param_cod access_cod()
mem_fixed_allocator * allocator
mem_fixed_allocator * get_allocator()
ui32 precinct_scratch_needed_bytes
void check_broadcast_validity()
param_qcd * access_qcd(ui32 comp_num)
void read_headers(infile_base *file)
const param_cod * get_cod()
void set_profile(const char *s)
bool employ_color_transform
void write_headers(outfile_base *file)
ui32 get_skipped_res_for_recon()
line_buf * pull(ui32 &comp_num)
ui32 skipped_res_for_read
bool get_top_left_precinct(point &top_left)
void parse_one_precinct(ui32 &data_left, infile_base *file)
bool skipped_res_for_recon
mem_elastic_allocator * elastic
void write_precincts(outfile_base *file)
resolution * next_resolution()
bool skipped_res_for_read
void finalize_alloc(codestream *codestream, const rect &res_rect, const rect &recon_res_rect, ui32 comp_num, ui32 res_num, point comp_downsamp, tile_comp *parent_tile_comp, resolution *parent_res)
void parse_all_precincts(ui32 &data_left, infile_base *file)
static void pre_alloc(codestream *codestream, const rect &res_rect, const rect &recon_res_rect, ui32 res_num)
void write_one_precinct(outfile_base *file)
void exchange_buf(line_buf *l)
coded_cb_header * coded_cbs
void get_cb_indices(const size &num_precincts, precinct *precincts)
mem_elastic_allocator * elastic
static void pre_alloc(codestream *codestream, const rect &band_rect, ui32 res_num)
void finalize_alloc(codestream *codestream, const rect &band_rect, resolution *res, ui32 res_num, ui32 subband_num)
static void pre_alloc(codestream *codestream, const rect &comp_rect, const rect &recon_comp_rect)
ui32 get_num_decompositions()
bool get_top_left_precinct(ui32 res_num, point &top_left)
void write_one_precinct(ui32 res_num, outfile_base *file)
void finalize_alloc(codestream *codestream, tile *parent, ui32 comp_num, const rect &comp_rect, const rect &recon_comp_rect)
void parse_one_precinct(ui32 res_num, ui32 &data_left, infile_base *file)
ojph::point comp_downsamp
void write_precincts(ui32 res_num, outfile_base *file)
void parse_precincts(ui32 res_num, ui32 &data_left, infile_base *file)
bool pull(line_buf *, ui32 comp_num)
void finalize_alloc(codestream *codestream, const rect &tile_rect, const rect &recon_tile_rect, ui32 tile_idx, ui32 offset)
void fill_tlm(param_tlm *tlm)
static void pre_alloc(codestream *codestream, const rect &tile_rect, const rect &recon_tile_rect)
void flush(outfile_base *file)
ui32 skipped_res_for_read
bool push(line_buf *line, ui32 comp_num)
bool employ_color_transform
void parse_tile_header(const param_sot &sot, infile_base *file, const ui64 &tile_start_location)
void get_buffer(ui32 needed_bytes, coded_lists *&p)
void pre_alloc_data(size_t num_ele, ui32 pre_size)
void pre_alloc_obj(size_t num_ele)
T * post_alloc_obj(size_t num_ele)
T * post_alloc_data(size_t num_ele, ui32 pre_size)
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 bool get_block_vertical_causality() const
OJPH_EXPORT size get_log_precinct_size(ui32 level_num) 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 bool bb_read_chunk(bit_read_buf *bbp, ui32 num_bytes, coded_lists *&cur_coded_list, mem_elastic_allocator *elastic)
void(* cnvrt_float_to_si32)(const float *sp, si32 *dp, float mul, ui32 width)
static int find_marker(infile_base *f, const ui16 *char_list, int list_len)
static bool bb_read_bit(bit_read_buf *bbp, ui32 &bit)
static int skip_marker(infile_base *file, const char *marker, const char *msg, int msg_level, bool resilient)
static void bb_terminate(bit_write_buf *bbp)
void(* irrev_horz_wvlt_fwd_tx)(line_buf *src, line_buf *ldst, line_buf *hdst, ui32 width, bool even)
static void bb_init(bit_write_buf *bbp, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list)
void(* cnvrt_si32_to_float_shftd)(const si32 *sp, float *dp, float mul, ui32 width)
void(* ict_forward)(const float *r, const float *g, const float *b, float *y, float *cb, float *cr, ui32 repeat)
void(* rev_horz_wvlt_bwd_tx)(line_buf *dst, line_buf *lsrc, line_buf *hsrc, ui32 width, bool even)
void(* cnvrt_si32_to_si32_shftd)(const si32 *sp, si32 *dp, int shift, ui32 width)
static bool bb_read_bits(bit_read_buf *bbp, int num_bits, ui32 &bits)
static bool bb_skip_sop(bit_read_buf *bbp)
void(* ict_backward)(const float *y, const float *cb, const float *cr, float *r, float *g, float *b, ui32 repeat)
static void rotate_buffers(line_buf *line1, line_buf *line2, line_buf *line3, line_buf *line4)
void(* rct_backward)(const si32 *y, const si32 *cb, const si32 *cr, si32 *r, si32 *g, si32 *b, ui32 repeat)
void init_wavelet_transform_functions()
void init_colour_transform_functions()
void(* rev_vert_wvlt_fwd_update)(const line_buf *src1, const line_buf *src2, line_buf *dst, ui32 repeat)
static bool bb_read(bit_read_buf *bbp)
void(* cnvrt_float_to_si32_shftd)(const float *sp, si32 *dp, float mul, ui32 width)
static ui32 log2ceil(ui32 x)
static void bb_put_bits(bit_write_buf *bbp, ui32 data, int num_bits, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list, ui32 &ph_bytes)
void(* cnvrt_si32_to_float)(const si32 *sp, float *dp, float mul, ui32 width)
void(* rev_horz_wvlt_fwd_tx)(line_buf *src, line_buf *ldst, line_buf *hdst, ui32 width, bool even)
void(* irrev_vert_wvlt_step)(const line_buf *src1, const line_buf *src2, line_buf *dst, int step_num, ui32 repeat)
void(* rct_forward)(const si32 *r, const si32 *g, const si32 *b, si32 *y, si32 *cb, si32 *cr, ui32 repeat)
static ui16 swap_byte(ui16 t)
void(* rev_vert_wvlt_bwd_update)(const line_buf *src1, const line_buf *src2, line_buf *dst, ui32 repeat)
void(* rev_vert_wvlt_bwd_predict)(const line_buf *src1, const line_buf *src2, line_buf *dst, ui32 repeat)
bool ojph_decode_codeblock(ui8 *coded_data, ui32 *decoded_data, ui32 missing_msbs, ui32 num_passes, ui32 lengths1, ui32 lengths2, ui32 width, ui32 height, ui32 stride, bool stripe_causal)
Decodes one codeblock, processing the cleanup, siginificance propagation, and magnitude refinement pa...
void(* rev_vert_wvlt_fwd_predict)(const line_buf *src1, const line_buf *src2, line_buf *dst, ui32 repeat)
void(* irrev_horz_wvlt_bwd_tx)(line_buf *src, line_buf *ldst, line_buf *hdst, ui32 width, bool even)
void(* irrev_vert_wvlt_K)(const line_buf *src, line_buf *dst, bool L_analysis_or_H_synthesis, ui32 repeat)
static void bb_put_bit(bit_write_buf *bbp, ui32 bit, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list, ui32 &ph_bytes)
static void bb_skip_eph(bit_read_buf *bbp)
void ojph_encode_codeblock(ui32 *buf, ui32 missing_msbs, ui32 num_passes, ui32 width, ui32 height, ui32 stride, ui32 *lengths, ojph::mem_elastic_allocator *elastic, ojph::coded_lists *&coded)
static void bb_expand_buf(bit_write_buf *bbp, mem_elastic_allocator *elastic, coded_lists *&cur_coded_list)
const char OJPH_PN_STRING_BROADCAST[]
const char OJPH_PN_STRING_IMF[]
static si32 ojph_trunc(float val)
static ui32 count_leading_zeros(ui32 val)
#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
bool packets_use_eph() const
ui8 get_num_decompositions() const
bool packets_may_use_sop() const
bool is_reversible() const
void read(infile_base *file, ui32 num_comps)
ui32 get_Kmax(ui32 resolution, ui32 subband) const
void check_validity(const param_siz &siz, const param_cod &cod)
bool write(outfile_base *file)
void read(infile_base *file)
float irrev_get_delta(ui32 resolution, ui32 subband) const
void set_skipped_resolutions(ui32 skipped_resolutions)
ui32 get_bit_depth(ui32 comp_num) const
ui32 get_recon_height(ui32 comp_num) const
bool is_signed(ui32 comp_num) const
bool write(outfile_base *file)
ui16 get_num_components() const
ui32 get_height(ui32 comp_num) const
point get_downsampling(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
void init(ui32 payload_length=0, ui16 tile_idx=0, ui8 tile_part_index=0, ui8 num_tile_parts=0)
ui16 get_tile_index() const
bool read(infile_base *file, bool resilient)
ui8 get_tile_part_index() const
ui32 get_payload_length() const
bool write(outfile_base *file, ui32 payload_len)
void set_next_pair(ui16 Ttlm, ui32 Ptlm)
bool write(outfile_base *file)
void init(ui32 num_pairs, Ttlm_Ptlm_pair *store)
void write(outfile_base *file)
ui32 prepare_precinct(int tag_tree_size, ui32 *lev_idx, mem_elastic_allocator *elastic)
void parse(int tag_tree_size, ui32 *lev_idx, mem_elastic_allocator *elastic, ui32 &data_left, infile_base *file, bool skipped)
ui8 * get(ui32 x, ui32 y, ui32 lev)
void init(ui8 *buf, ui32 *lev_idx, ui32 num_levels, size s, int init_val)