38#define _USE_MATH_DEFINES
169 if (num_decompositions > 32)
171 "maximum number of decompositions cannot exceed 32");
178 ui32 log_width = 31 - count_leading_zeros(width);
179 ui32 log_height = 31 - count_leading_zeros(height);
180 if (width == 0 || width != (1u << log_width)
181 || height == 0 || height != (1u << log_height)
182 || log_width < 2 || log_height < 2
183 || log_width + log_height > 12)
184 OJPH_ERROR(0x00050011,
"incorrect code block dimensions");
192 if (num_levels == 0 || precinct_size == NULL)
199 size t = precinct_size[i < num_levels ? i : num_levels - 1];
201 ui32 PPx = 31 - count_leading_zeros(t.
w);
202 ui32 PPy = 31 - count_leading_zeros(t.
h);
203 if (t.
w == 0 || t.
h == 0)
204 OJPH_ERROR(0x00050021,
"precinct width or height cannot be 0");
205 if (t.
w != (1u<<PPx) || t.
h != (1u<<PPy))
207 "precinct width and height should be a power of 2");
208 if (PPx > 15 || PPy > 15)
209 OJPH_ERROR(0x00050023,
"precinct size is too large");
210 if (i > 0 && (PPx == 0 || PPy == 0))
211 OJPH_ERROR(0x00050024,
"precinct size is too small");
221 size_t len = strlen(name);
235 OJPH_ERROR(0x00050031,
"unknown progression order");
238 OJPH_ERROR(0x00050032,
"improper progression order");
420 const float weights[])
438 size_t num_weights,
const float weights[])
465 ui8 decoded_bit_depth,
466 bool decoded_signedness,
468 ui16 num_points,
void* points,
470 bool approx_encoding_nlt,
474 decoded_signedness, d_min, d_max, pt_val, num_points, points, nl_type,
475 approx_encoding_nlt, num_enc_points);
480 ui8& decoded_bit_depth,
481 bool& decoded_signedness,
485 decoded_signedness, nl_type);
499 size_t t = strlen(str);
502 "COM marker string length cannot be larger than 65531");
513 "COM marker string length cannot be larger than 65531");
548 1.4021e+00f, 2.0304e+00f, 2.9012e+00f, 4.1153e+00f, 5.8245e+00f,
549 8.2388e+00f, 1.1652e+01f, 1.6479e+01f, 2.3304e+01f, 3.2957e+01f,
550 4.6609e+01f, 6.5915e+01f, 9.3217e+01f, 1.3183e+02f, 1.8643e+02f,
551 2.6366e+02f, 3.7287e+02f, 5.2732e+02f, 7.4574e+02f, 1.0546e+03f,
552 1.4915e+03f, 2.1093e+03f, 2.9830e+03f, 4.2185e+03f, 5.9659e+03f,
553 8.4371e+03f, 1.1932e+04f, 1.6874e+04f, 2.3864e+04f, 3.3748e+04f,
554 4.7727e+04f, 6.7496e+04f, 9.5454e+04f };
556 1.9669e+00f, 2.8839e+00f, 4.1475e+00f, 5.8946e+00f, 8.3472e+00f,
557 1.1809e+01f, 1.6701e+01f, 2.3620e+01f, 3.3403e+01f, 4.7240e+01f,
558 6.6807e+01f, 9.4479e+01f, 1.3361e+02f, 1.8896e+02f, 2.6723e+02f,
559 3.7792e+02f, 5.3446e+02f, 7.5583e+02f, 1.0689e+03f, 1.5117e+03f,
560 2.1378e+03f, 3.0233e+03f, 4.2756e+03f, 6.0467e+03f, 8.5513e+03f,
561 1.2093e+04f, 1.7103e+04f, 2.4187e+04f, 3.4205e+04f, 4.8373e+04f,
562 6.8410e+04f, 9.6747e+04f, 1.3682e+05f };
564 1.2247e+00f, 1.3229e+00f, 1.5411e+00f, 1.7139e+00f, 1.9605e+00f,
565 2.2044e+00f, 2.5047e+00f, 2.8277e+00f, 3.2049e+00f, 3.6238e+00f,
566 4.1033e+00f, 4.6423e+00f, 5.2548e+00f, 5.9462e+00f, 6.7299e+00f,
567 7.6159e+00f, 8.6193e+00f, 9.7544e+00f, 1.1039e+01f, 1.2493e+01f,
568 1.4139e+01f, 1.6001e+01f, 1.8108e+01f, 2.0493e+01f, 2.3192e+01f,
569 2.6246e+01f, 2.9702e+01f, 3.3614e+01f, 3.8041e+01f, 4.3051e+01f,
570 4.8721e+01f, 5.5138e+01f, 6.2399e+01f };
572 1.3975e+00f, 1.4389e+00f, 1.7287e+00f, 1.8880e+00f, 2.1841e+00f,
573 2.4392e+00f, 2.7830e+00f, 3.1341e+00f, 3.5576e+00f, 4.0188e+00f,
574 4.5532e+00f, 5.1494e+00f, 5.8301e+00f, 6.5963e+00f, 7.4663e+00f,
575 8.4489e+00f, 9.5623e+00f, 1.0821e+01f, 1.2247e+01f, 1.3860e+01f,
576 1.5685e+01f, 1.7751e+01f, 2.0089e+01f, 2.2735e+01f, 2.5729e+01f,
577 2.9117e+01f, 3.2952e+01f, 3.7292e+01f, 4.2203e+01f, 4.7761e+01f,
578 5.4051e+01f, 6.1170e+01f, 6.9226e+01f };
599 1.3328e+00f, 1.3067e+00f, 1.3028e+00f, 1.3001e+00f, 1.2993e+00f,
600 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
601 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
602 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
603 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
604 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f, 1.2992e+00f,
605 1.2992e+00f, 1.2992e+00f };
607 1.2757e+00f, 1.2352e+00f, 1.2312e+00f, 1.2285e+00f, 1.2280e+00f,
608 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
609 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
610 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
611 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
612 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f, 1.2278e+00f,
613 1.2278e+00f, 1.2278e+00f };
615 1.6250e+00f, 1.6875e+00f, 1.6963e+00f, 1.7067e+00f, 1.7116e+00f,
616 1.7129e+00f, 1.7141e+00f, 1.7145e+00f, 1.7151e+00f, 1.7152e+00f,
617 1.7155e+00f, 1.7155e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
618 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
619 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
620 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f, 1.7156e+00f,
621 1.7156e+00f, 1.7156e+00f };
623 2.7500e+00f, 2.8047e+00f, 2.8198e+00f, 2.8410e+00f, 2.8558e+00f,
624 2.8601e+00f, 2.8628e+00f, 2.8656e+00f, 2.8662e+00f, 2.8667e+00f,
625 2.8669e+00f, 2.8670e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
626 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
627 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
628 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f, 2.8671e+00f,
629 2.8671e+00f, 2.8671e+00f };
649 if (component_subsampling.
x == 2 && component_subsampling.
y == 2)
651 else if (component_subsampling.
x == 2 && component_subsampling.
y == 1)
653 else if (component_subsampling.
x == 1 && component_subsampling.
y == 1)
664 else if (
comp_type == comp_type::OJPH_COMP_CB)
674 else if (
comp_type == comp_type::OJPH_COMP_CR)
697 if (subband_idx == 0)
700 assert(subband_idx >= 1 && subband_idx <= 3);
701 assert(decomposition_level > 0);
702 decomposition_level =
ojph_min(decomposition_level, 6);
703 ui32 index = (decomposition_level - 1) * 3 + (3 - subband_idx);
713 else if (
comp_type == comp_type::OJPH_COMP_CB)
714 return 1.8051f / 1.7321f;
715 else if (
comp_type == comp_type::OJPH_COMP_CR)
716 return 1.5734f / 1.7321f;
728 constexpr float t0 = 65.0f;
729 constexpr float t1 = 97.0f;
730 constexpr float alpha_t0 = 0.04f, alpha_t1 = 0.10f;
731 constexpr float m_t0 = 2.0f * (1.0f - t0 / 100.0f);
732 constexpr float m_t1 = 2.0f * (1.0f - t1 / 100.0f);
736 m_q = 50.0f / qfactor;
738 m_q = 2.0f * (1.0f - qfactor / 100.0f);
746 else if (qfactor < t1)
748 power = std::log(m_q) - std::log(m_t1);
749 power /= std::log(m_t0) - std::log(m_t1);
750 alpha_q = alpha_t1 * std::pow(alpha_t0 / alpha_t1, power);
757 const float eps = std::sqrt(0.5f) * std::ldexp(1.0f, -(
int)bit_depth);
758 return alpha_q * m_q + eps;
768 static const float y[19];
774 0.2724f, 0.5128f, 0.5128f,
775 0.6692f, 0.9382f, 0.9382f,
776 1.0888f, 1.3046f, 1.3046f,
777 1.4156f, 1.5594f, 1.5594f,
779 2.0f, 2.0f, 2.0f, 2.0f};
781 0.5196f, 0.8260f, 0.8260f,
782 1.0080f, 1.2928f, 1.2928f,
783 1.4440f, 1.6508f, 1.6508f,
784 1.7538f, 1.8848f, 1.8848f,
786 2.0f, 2.0f, 2.0f, 2.0f};
788 0.1220f, 0.1220f, 0.3626f,
789 0.3626f, 0.3626f, 0.6634f,
790 0.6634f, 0.6634f, 0.9225f,
791 0.9225f, 0.9225f, 1.1027f,
792 1.1027f, 1.1027f, 1.4142f,
793 1.4142f, 1.4142f, 1.4142f, 1.4142f};
795 0.2595f, 0.2595f, 0.5841f,
796 0.5841f, 0.5841f, 0.9141f,
797 0.9141f, 0.9141f, 1.1673f,
798 1.1673f, 1.1673f, 1.3328f,
799 1.3328f, 1.3328f, 1.4142f,
800 1.4142f, 1.4142f, 1.4142f, 1.4142f};
802 0.0263f, 0.0863f, 0.0863f,
803 0.1362f, 0.2564f, 0.2564f,
804 0.3346f, 0.4691f, 0.4691f,
805 0.5444f, 0.6523f, 0.6523f,
806 0.7078f, 0.7797f, 0.7797f,
807 1.0f, 1.0f, 1.0f, 1.0f};
809 0.0773f, 0.1835f, 0.1835f,
810 0.2598f, 0.4130f, 0.4130f,
811 0.5040f, 0.6464f, 0.6464f,
812 0.7220f, 0.8254f, 0.8254f,
813 0.8769f, 0.9424f, 0.9424f,
814 1.0f, 1.0f, 1.0f, 1.0f};
816 0.0901f, 0.2758f, 0.2758f,
817 0.7018f, 0.8378f, 0.8378f,
821 1.0f, 1.0f, 1.0f, 1.0f};
828 1.0f, 1.0f, 1.0f, 1.0f};
851 buf2 = swap_bytes_if_le(buf2);
853 buf2 = swap_bytes_if_le(
Lsiz);
855 buf2 = swap_bytes_if_le(
Rsiz);
857 buf4 = swap_bytes_if_le(
Xsiz);
859 buf4 = swap_bytes_if_le(
Ysiz);
861 buf4 = swap_bytes_if_le(
XOsiz);
863 buf4 = swap_bytes_if_le(
YOsiz);
865 buf4 = swap_bytes_if_le(
XTsiz);
867 buf4 = swap_bytes_if_le(
YTsiz);
869 buf4 = swap_bytes_if_le(
XTOsiz);
871 buf4 = swap_bytes_if_le(
YTOsiz);
873 buf2 = swap_bytes_if_le(
Csiz);
875 for (
int c = 0; c <
Csiz; ++c)
878 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
880 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
882 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
892 OJPH_ERROR(0x00050041,
"error reading SIZ marker");
894 int num_comps = (
Lsiz - 38) / 3;
895 if (
Lsiz != 38 + 3 * num_comps)
896 OJPH_ERROR(0x00050042,
"error in SIZ marker length");
898 OJPH_ERROR(0x00050043,
"error reading SIZ marker");
900 if ((
Rsiz & 0x4000) == 0)
902 "Rsiz bit 14 is not set (this is not a JPH file)");
903 if ((
Rsiz & 0x8000) != 0 && (
Rsiz & 0xD5F) != 0)
904 OJPH_WARN(0x00050001,
"Rsiz in SIZ has unimplemented fields");
906 OJPH_ERROR(0x00050045,
"error reading SIZ marker");
909 OJPH_ERROR(0x00050046,
"error reading SIZ marker");
911 ui32 t_XOsiz, t_YOsiz;
912 if (file->
read(&t_XOsiz, 4) != 4)
913 OJPH_ERROR(0x00050047,
"error reading SIZ marker");
914 if (file->
read(&t_YOsiz, 4) != 4)
915 OJPH_ERROR(0x00050048,
"error reading SIZ marker");
917 swap_bytes_if_le(t_XOsiz),
918 swap_bytes_if_le(t_YOsiz)));
919 ui32 t_XTsiz, t_YTsiz;
920 if (file->
read(&t_XTsiz, 4) != 4)
921 OJPH_ERROR(0x00050049,
"error reading SIZ marker");
922 if (file->
read(&t_YTsiz, 4) != 4)
923 OJPH_ERROR(0x0005004A,
"error reading SIZ marker");
925 swap_bytes_if_le(t_XTsiz),
926 swap_bytes_if_le(t_YTsiz)));
927 ui32 t_XTOsiz, t_YTOsiz;
928 if (file->
read(&t_XTOsiz, 4) != 4)
929 OJPH_ERROR(0x0005004B,
"error reading SIZ marker");
930 if (file->
read(&t_YTOsiz, 4) != 4)
931 OJPH_ERROR(0x0005004C,
"error reading SIZ marker");
933 swap_bytes_if_le(t_XTOsiz),
934 swap_bytes_if_le(t_YTOsiz)));
936 OJPH_ERROR(0x0005004D,
"error reading SIZ marker");
938 if (
Csiz != num_comps)
939 OJPH_ERROR(0x0005004E,
"Csiz does not match the SIZ marker size");
941 OJPH_ERROR(0x0005004F,
"Wrong Csiz value of 0 in SIZ marker segment");
943 for (
int c = 0; c <
Csiz; ++c)
946 OJPH_ERROR(0x00050051,
"error reading SIZ marker");
948 OJPH_ERROR(0x00050052,
"error reading SIZ marker");
950 OJPH_ERROR(0x00050053,
"error reading SIZ marker");
951 if ((
cptr[c].SSiz & 0x7F) > 37)
952 OJPH_ERROR(0x00050054,
"Wrong SIZ-SSiz value of %d",
cptr[c].SSiz);
953 if (
cptr[c].XRsiz == 0)
954 OJPH_ERROR(0x00050055,
"Wrong SIZ-XRsiz value of %d",
cptr[c].XRsiz);
955 if (
cptr[c].YRsiz == 0)
956 OJPH_ERROR(0x00050056,
"Wrong SIZ-YRsiz value of %d",
cptr[c].YRsiz);
1015 buf2 = swap_bytes_if_le(buf2);
1017 buf2 = swap_bytes_if_le(
Lcap);
1019 buf4 = swap_bytes_if_le(
Pcap);
1022 buf2 = swap_bytes_if_le(
Ccap[0]);
1032 OJPH_ERROR(0x00050061,
"error reading CAP marker");
1035 OJPH_ERROR(0x00050062,
"error reading CAP marker");
1037 ui32 count = population_count(
Pcap);
1038 if (
Pcap & 0xFFFDFFFF)
1040 "error Pcap in CAP has options that are not supported");
1041 if ((
Pcap & 0x00020000) == 0)
1043 "error Pcap should have its 15th MSB set, Pcap^15. "
1044 " This is not a JPH file");
1045 for (
ui32 i = 0; i < count; ++i)
1047 OJPH_ERROR(0x00050065,
"error reading CAP marker");
1048 if (
Lcap != 6 + 2 * count)
1049 OJPH_ERROR(0x00050066,
"error in CAP marker length");
1066 assert(
atk != NULL);
1085 buf2 = swap_bytes_if_le(buf2);
1087 buf2 = swap_bytes_if_le(
Lcod);
1090 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1092 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1096 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1098 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1100 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1102 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1104 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1106 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1111 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1138 Lcod = num_comps < 257 ? 9 : 10;
1146 buf2 = swap_bytes_if_le(buf2);
1148 buf2 = swap_bytes_if_le(
Lcod);
1150 if (num_comps < 257)
1153 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1161 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1163 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1165 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1167 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1169 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1171 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1176 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1188 OJPH_ERROR(0x00050071,
"error reading COD segment");
1191 OJPH_ERROR(0x00050072,
"error reading COD segment");
1193 OJPH_ERROR(0x00050073,
"error reading COD segment");
1195 {
OJPH_ERROR(0x00050074,
"error reading COD segment"); }
1199 OJPH_ERROR(0x00050075,
"error reading COD segment");
1201 OJPH_ERROR(0x00050076,
"error reading COD segment");
1203 OJPH_ERROR(0x00050077,
"error reading COD segment");
1205 OJPH_ERROR(0x00050078,
"error reading COD segment");
1207 OJPH_ERROR(0x00050079,
"error reading COD segment");
1209 OJPH_ERROR(0x0005007A,
"error reading COD segment");
1217 OJPH_ERROR(0x0005007D,
"wrong settings in a COD-SPcod parameter");
1220 OJPH_ERROR(0x0005007E,
"unsupported settings in a COD-SPcod parameter");
1224 for (
int i = 0; i <= num_decompositions; ++i) {
1226 OJPH_ERROR(0x0005007B,
"error reading COD segment");
1231 "Precinct width or height for resolutions other than the"
1232 " coarsest must be larger than 1; here, they are %d and %d,"
1239 OJPH_ERROR(0x0005007C,
"error in COD segment length");
1252 OJPH_ERROR(0x00050121,
"error reading COC segment");
1254 if (num_comps < 257) {
1256 if (file->
read(&t, 1) != 1)
1257 OJPH_ERROR(0x00050122,
"error reading COC segment");
1262 OJPH_ERROR(0x00050123,
"error reading COC segment");
1266 OJPH_ERROR(0x00050124,
"error reading COC segment");
1269 "Unsupported options in Scoc field of the COC segment");
1271 OJPH_ERROR(0x00050125,
"error reading COC segment");
1273 OJPH_ERROR(0x00050126,
"error reading COC segment");
1275 OJPH_ERROR(0x00050127,
"error reading COC segment");
1277 OJPH_ERROR(0x00050128,
"error reading COC segment");
1279 OJPH_ERROR(0x00050129,
"error reading COC segment");
1287 OJPH_ERROR(0x0005012C,
"wrong settings in a COC-SPcoc parameter");
1290 OJPH_ERROR(0x0005012D,
"unsupported settings in a COC-SPcoc parameter");
1294 for (
int i = 0; i <= num_decompositions; ++i) {
1296 OJPH_ERROR(0x0005012A,
"error reading COC segment");
1301 "Precinct width or height for resolutions other than the"
1302 " coarsest must be larger than 1; here, they are %d and %d,"
1309 t += num_comps < 257 ? 0 : 1;
1310 t += (
Scod & 1) ? 1 + num_decompositions : 0;
1312 OJPH_ERROR(0x0005012B,
"error in COC segment length");
1320 if (this->atk == NULL)
1321 OJPH_ERROR(0x00050131,
"A COD segment employs the DWT kernel "
1322 "atk = %d, but a corresponding ATK segment cannot be found.",
1329 OJPH_ERROR(0x00050132,
"A COC segment employs the DWT kernel "
1330 "atk = %d, but a corresponding ATK segment cannot be found",
1364 while (p->
next != NULL)
1406 for (
ui32 c = 0; c < num_comps; ++c)
1421 for (
ui32 i = 0; i < num_comps; ++i)
1431 else if (num_comps >= 3)
1433 for (
ui32 i = 0; i < num_comps; ++i) {
1438 ui8 ci = (
ui8)(i < 3u ? i : 0u);
1451 for (
ui32 c = 0; c < num_comps; ++c)
1476 OJPH_ERROR(0x000501C1,
"Quantization step sizes already initialized.");
1491 OJPH_ERROR(0x000501C2,
"Quantization weights for component %d can "
1492 "only be used with the irreversible transform.", comp_num);
1494 OJPH_ERROR(0x000501C3,
"Quantization weights for component %d "
1495 "cannot be used together with qfactor.", comp_num);
1497 OJPH_ERROR(0x000501C4,
"Component %d has %d quantization weights, "
1498 "but %d are needed for %d decomposition levels.", comp_num,
1513 OJPH_WARN(0x000501C5,
"qstep for component %d is ignored, because "
1514 "qfactor is set.", comp_num);
1525 OJPH_ERROR(0x000501D1,
"Quantization step sizes not initialized.");
1539 OJPH_ERROR(0x00050181,
"Qfactor must be between 1 and 100, "
1540 "but was set to %i.",
qfactor);
1547 bool is_employing_color_transform)
1550 B += is_employing_color_transform ? 1 : 0;
1553 ui32 X = (
ui32) ceil(log(bibo_l * bibo_l) / M_LN2);
1560 X = (
ui32) ceil(log(bibo_h * bibo_l) / M_LN2);
1562 max_B_plus_X =
ojph_max(max_B_plus_X, B + X);
1564 max_B_plus_X =
ojph_max(max_B_plus_X, B + X);
1565 X = (
ui32) ceil(log(bibo_h * bibo_h) / M_LN2);
1567 max_B_plus_X =
ojph_max(max_B_plus_X, B + X);
1570 if (max_B_plus_X > 38)
1571 OJPH_ERROR(0x00050151,
"The specified combination of bit_depth, "
1572 "colour transform, and type of wavelet transform requires more than "
1573 "38 bits; it requires %d bits. This is beyond what is allowed in "
1574 "the JPEG2000 image coding format.", max_B_plus_X);
1577 Sqcd = (
ui8)(guard_bits << 5);
1596 Sqcd = (
ui8)((guard_bits<<5)|0x2);
1608 OJPH_ERROR(0x00050161,
"Qfactor can only be used on components "
1609 "with 4:4:4, 4:2:2 or 4:2:0 sampling");
1610 if (this->
ctype == comp_type::OJPH_COMP_Y &&
1611 this->
sampling.
x != 1 && this->sampling.y != 1)
1612 OJPH_ERROR(0x00050162,
"Qfactor can only be used for a Y or "
1613 "luminance component when it is not downsampled.");
1628 auto get_sqrt_weight = [&](
ui32 d,
ui32 sb) ->
float
1634 static const ui32 pos[4] = { 0, 1, 0, 2 };
1635 return this->weights[(d - 1) * 3 + pos[sb]];
1643 w_b = std::pow(w_b, power);
1644 encode_SPqcd(b++, delta_ref / (gain_l * gain_l * g_c * w_b));
1653 w_b = get_sqrt_weight(d, 1);
1654 w_b = std::pow(w_b, power);
1655 encode_SPqcd(b++, delta_ref / (gain_h * gain_l * g_c * w_b));
1656 w_b = get_sqrt_weight(d, 2);
1657 w_b = std::pow(w_b, power);
1658 encode_SPqcd(b++, delta_ref / (gain_l * gain_h * g_c * w_b));
1659 w_b = get_sqrt_weight(d, 3);
1660 w_b = std::pow(w_b, power);
1661 encode_SPqcd(b++, delta_ref / (gain_h * gain_h * g_c * w_b));
1668 int exp = 0, mantissa;
1669 while (delta < 1.0f)
1670 { exp++; delta *= 2.0f; }
1671 mantissa = (int)round(delta * (
float)(1<<11)) - (1<<11);
1674 mantissa = mantissa < (1<<11) ? mantissa : 0x7FF;
1675 SPqcd.u16[subband_index] = (
ui16)((exp << 11) | mantissa);
1690 int irrev = p->
Sqcd & 0x1F;
1697 else if (irrev == 2)
1715 ui32 num_decompositions,
ui32 comp_num,
1718 float arr[] = { 1.0f, 2.0f, 2.0f, 4.0f };
1719 if ((
Sqcd & 0x1F) != 2)
1720 OJPH_ERROR(0x00050101,
"There is something wrong in the configuration "
1721 "of the codestream; for component %d, the codestream defines an "
1722 "irreversible transform, for which the codestream provides a "
1723 "reversible (no quantization) step sizes in Sqcd/Sqcc.", comp_num);
1726 if (dfs != NULL && dfs->
exists())
1731 OJPH_INFO(0x00050102,
"Trying to access quantization step size for "
1732 "subband %d when the QCD/QCC marker segment specifies "
1733 "quantization step sizes for %d subbands only. To continue "
1734 "decoding, we are using the step size for subband %d, which can "
1735 "produce incorrect results",
1739 int eps =
SPqcd.u16[idx] >> 11;
1741 mantissa = (float)((
SPqcd.u16[idx] & 0x7FF) | 0x800) * arr[
subband];
1742 mantissa /= (float)(1 << 11);
1743 mantissa /= (float)(1u << eps);
1754 if (
main->is_employing_color_transform() &&
comp_idx < 3)
1756 for (
ui32 i = 0; i < 3; ++i) {
1769 return precision + 1 + 1;
1783 if (dfs != NULL && dfs->
exists())
1788 OJPH_INFO(0x00050111,
"Trying to access quantization step size for "
1789 "subband %d when the QCD/QCC marker segment specifies "
1790 "quantization step sizes for %d subbands only. To continue "
1791 "decoding, we are using the step size for subband %d, which can "
1792 "produce incorrect results",
1797 int irrev =
Sqcd & 0x1F;
1802 num_bits = num_bits == 0 ? 0 : num_bits - 1;
1804 else if (irrev == 1)
1806 else if (irrev == 2)
1807 num_bits = (
SPqcd.u16[idx] >> 11) - 1;
1817 int irrev =
Sqcd & 0x1F;
1823 num_bits =
ojph_max(num_bits, t == 0 ? 0 : t - 1);
1826 else if (irrev == 1)
1828 else if (irrev == 2)
1844 int irrev =
Sqcd & 0x1F;
1850 else if (irrev == 2)
1860 buf2 = swap_bytes_if_le(buf2);
1862 buf2 = swap_bytes_if_le(
Lqcd);
1865 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1871 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1873 else if (irrev == 2)
1876 buf2 = swap_bytes_if_le(
SPqcd.u16[i]);
1903 int irrev =
Sqcd & 0x1F;
1906 Lqcd = (
ui16)(4 + (num_comps < 257 ? 0 : 1));
1909 else if (irrev == 2)
1919 buf2 = swap_bytes_if_le(buf2);
1921 buf2 = swap_bytes_if_le(
Lqcd);
1923 if (num_comps < 257)
1926 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1934 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1939 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
1941 else if (irrev == 2)
1944 buf2 = swap_bytes_if_le(
SPqcd.u16[i]);
1970 OJPH_ERROR(0x00050081,
"error reading QCD marker");
1973 OJPH_ERROR(0x00050082,
"error reading QCD marker");
1974 if ((
Sqcd & 0x1F) == 0)
1978 OJPH_ERROR(0x0005008A,
"QCD marker segment that specifies no "
1979 "quantization informtion");
1981 OJPH_ERROR(0x00050083,
"wrong Lqcd value of %d in QCD marker",
Lqcd);
1984 OJPH_ERROR(0x00050084,
"error reading QCD marker");
1986 else if ((
Sqcd & 0x1F) == 1)
1990 "Scalar derived quantization is not supported yet in QCD marker");
1992 OJPH_ERROR(0x00050085,
"wrong Lqcd value in QCD marker");
1994 else if ((
Sqcd & 0x1F) == 2)
1998 OJPH_ERROR(0x0005008B,
"QCD marker segment that specifies no "
1999 "quantization informtion");
2001 OJPH_ERROR(0x00050086,
"wrong Lqcd value of %d in QCD marker",
Lqcd);
2005 OJPH_ERROR(0x00050087,
"error reading QCD marker");
2006 SPqcd.u16[i] = swap_bytes_if_le(
SPqcd.u16[i]);
2010 OJPH_ERROR(0x00050088,
"wrong Sqcd value in QCD marker");
2017 OJPH_ERROR(0x000500A1,
"error reading QCC marker");
2019 if (num_comps < 257)
2022 if (file->
read(&v, 1) != 1)
2023 OJPH_ERROR(0x000500A2,
"error reading QCC marker");
2029 OJPH_ERROR(0x000500A3,
"error reading QCC marker");
2033 OJPH_ERROR(0x000500A4,
"error reading QCC marker");
2034 ui32 offset = num_comps < 257 ? 4 : 5;
2035 if ((
Sqcd & 0x1F) == 0)
2039 OJPH_ERROR(0x000500AC,
"QCC marker segment that specifies no "
2040 "quantization informtion");
2042 OJPH_ERROR(0x000500A5,
"wrong Lqcd value of %d in QCC marker",
Lqcd);
2045 OJPH_ERROR(0x000500A6,
"error reading QCC marker");
2047 else if ((
Sqcd & 0x1F) == 1)
2051 "Scalar derived quantization is not supported yet in QCC marker");
2053 OJPH_ERROR(0x000500A7,
"wrong Lqcc value in QCC marker");
2055 else if ((
Sqcd & 0x1F) == 2)
2059 OJPH_ERROR(0x000500AD,
"QCC marker segment that specifies no "
2060 "quantization informtion");
2062 OJPH_ERROR(0x000500A8,
"wrong Lqcc value of %d in QCC marker",
Lqcd);
2066 OJPH_ERROR(0x000500A9,
"error reading QCC marker");
2067 SPqcd.u16[i] = swap_bytes_if_le(
SPqcd.u16[i]);
2071 OJPH_ERROR(0x000500AA,
"wrong Sqcc value in QCC marker");
2088 OJPH_ERROR(0x000501A1,
"The number of quantization weights must be "
2089 "between 1 and %d, but %zu were provided.",
2093 OJPH_ERROR(0x000501A2,
"Quantization weights must be positive.");
2116 OJPH_ERROR(0x00050191,
"Qfactor must be between 1 and 100, "
2117 "but was set to %i.",
qfactor);
2155 while (p->
next != NULL)
2179 double d = 1.0 / (double)((1ull << 32) - 1);
2185 float divider = (float)(1.0 / (
double)(1ull <<
get_bit_depth()));
2190 *dp++ = *sp++ * divider;
2198 *dp++ = *sp++ * divider;
2206 *dp++ = (
float)*sp++ * divider;
2215 template<
typename T>
2218 float& ft_min,
float& ft_max,
float& delta,
float& inv_delta,
2219 float fd_min,
float fd_max,
ui32 num_points,
ui32 enc_num_points,
2220 float* approx_enc_points)
2222 const T* p = (
const T*)marker_points;
2223 ft_min = (float)p[0] * div;
2224 ft_max = (float)p[num_points - 1] * div;
2225 delta = (ft_max - ft_min) / (
float)(enc_num_points - 1);
2226 inv_delta = (float)(enc_num_points - 1) / (ft_max - ft_min);
2229 float y_k = (float)p[k] * div, y_kp1 = (
float)p[k + 1] * div;
2230 float dt = (fd_max - fd_min) / (
float)(num_points - 1);
2231 float d_k = fd_min, d_kp1 = fd_min + dt;
2232 for (
ui32 i = 1; i < enc_num_points - 1; ++i)
2234 float z = ft_min + (float)i * delta;
2235 while (k + 1 < num_points - 1 && z >= y_kp1)
2239 d_kp1 = fd_min + (float)(k + 1) * dt;
2241 y_kp1 = (float)p[k + 1] * div;
2243 approx_enc_points[i] = d_k + (z - y_k) * dt / (y_kp1 - y_k);
2250 double d = 1.0 / (double)((1ull << 32) - 1);
2264 float mul = (float)((1ull <<
pt_val) - 1);
2265 float div = 1.0f / mul;
2288 double d = 1.0 / (double)((1ull << 32) - 1);
2292 float mul = (float)((1ull <<
pt_val) - 1);
2293 float div = 1.0f / mul;
2329 ui16 k = 0, old_k = 0;
2332 float z =
ft_min + (float)i * td;
2355 for (
ui32 c = 0; c < num_comps; ++c)
2363 if ((type == nonlinearity::OJPH_NLT_LUT_STYLE_NLT ||
2364 type == nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT) &&
2384 OJPH_ERROR(0x000501B1,
"The LUT style nonlinearities (type 2, LUT "
2385 "style, and type 4, binary complement followed by a LUT) are "
2386 "supported with the irreversible (9/7) wavelet only; component %d of "
2387 "this codestream is coded with the reversible (5/3) wavelet. Use the "
2388 "irreversible wavelet for that component, use the binary complement "
2389 "nonlinearity (type 3), or do not use a nonlinearity with it.",
2392 if (this->
enabled && this->
rec.
Tnlt == nonlinearity::OJPH_NLT_UNDEFINED)
2396 this->
rec.
Tnlt == nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT)
2398 bool all_same =
true;
2406 bool is_signed =
false;
2407 for (
ui32 c = 0; c < num_comps; ++c)
2416 all_same = all_same && (is_signed == siz.
is_signed(c));
2432 if (all_same && bit_depth != 0)
2440 for (
ui32 c = 0; c < num_comps; ++c)
2448 p->
rec.
Tnlt = nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT;
2458 for (
ui32 c = 0; c < num_comps; ++c)
2480 OJPH_ERROR(0x00050171,
"Nonliearities other than type 0 "
2481 "(No Nonlinearity) or type 3 (Binary Binary Complement to Sign "
2482 "Magnitude Conversion) are not supported in this function call");
2493 ui8 decoded_bit_depth,
2494 bool decoded_signedness,
2496 ui16 num_points,
void* points,
2498 bool approx_encoding_nlt,
2499 ui32 num_enc_points)
2503 OJPH_ERROR(0x000501A1,
"Nonliearities other than type 1 "
2504 "(LUT Nonlinearity) or type 4 (Binary Binary Complement to Sign "
2505 "Magnitude Conversion followed by LUT Nonlinearity) are not "
2506 "supported in this function call");
2507 if (pt_val == 0 || pt_val > 32)
2508 OJPH_ERROR(0x000501A2,
"pt_val must be larger than 0 and "
2509 "smaller than or equal to 32; you provided, %d", pt_val);
2510 if (decoded_bit_depth == 0 || decoded_bit_depth > 38)
2511 OJPH_ERROR(0x000501A3,
"decoded_bit_depth must be larger than 0 and "
2512 "smaller than or equal to 38; you provided, %d", decoded_bit_depth);
2514 OJPH_ERROR(0x000501A4,
"d_max must be larger than d_min; you "
2515 "provided %d and %d", d_min, d_max);
2516 if (num_points < 2 || num_points > 8192)
2517 OJPH_ERROR(0x000501A5,
"The number of points must be larger or equal "
2518 "to 2 and smaller or equal to 8192 -- the code will convert this "
2519 "number to a number in the range 1 to 8191 for the NLT marker "
2520 "segement; you provided %d", num_points);
2521 if (num_enc_points == 1)
2522 OJPH_ERROR(0x000501AA,
"The num_enc_points cannot be 1");
2530 (
ui8)((decoded_bit_depth - 1) | (decoded_signedness ? 0x80 : 0));
2541 ui32 v_min = 0, v_max = 0;
2542 ui32 smallest_gap = UINT_MAX;
2546 for (
int k = 0; k < num_points - 1; ++k)
2549 smallest_gap =
ojph_min(smallest_gap, (
ui32)(p[k+1] - p[k]));
2551 OJPH_ERROR(0x000501A6,
"The LUT must have increasing sequence "
2552 "of numbers; here we have at LUT[%d+1] <= LUT[%d], with values "
2553 "%d and %d.", k, k, p[k+1], p[k]);
2555 v_min = (
ui32)p[0]; v_max = (
ui32)p[num_points - 1];
2560 for (
int k = 0; k < num_points - 1; ++k)
2563 smallest_gap =
ojph_min(smallest_gap, (
ui32)(p[k+1] - p[k]));
2565 OJPH_ERROR(0x000501A7,
"The LUT must have increasing sequence "
2566 "of numbers; here we have at LUT[%d+1] <= LUT[%d], with values "
2567 "%d and %d.", k, k, p[k+1], p[k]);
2569 v_min = (
ui32)p[0]; v_max = (
ui32)p[num_points - 1];
2574 for (
int k = 0; k < num_points - 1; ++k)
2577 smallest_gap =
ojph_min(smallest_gap, p[k+1] - p[k]);
2579 OJPH_ERROR(0x000501A8,
"The LUT must have increasing sequence "
2580 "of numbers; here we have at LUT[%d+1] <= LUT[%d], with values "
2581 "%d and %d.", k, k, p[k+1], p[k]);
2583 v_min = (
ui32)p[0]; v_max = (
ui32)p[num_points - 1];
2589 ui32 ienc_pnts = num_enc_points;
2590 if (num_enc_points == 0)
2593 std::ceil((
float)(v_max-v_min) / (
float)(smallest_gap));
2594 if (enc_pnts > 8192.0f)
2597 OJPH_WARN(0x000501A1,
"Encoding with LUT is performed with an "
2598 "encoding LUT, derived from the LUT you provided; however, "
2599 "because the provided LUT has almost flat segment or segments, "
2600 "these are hard to invert. We are limiting the encoding "
2601 "LUT to 8192 entries, which means that some segment of the "
2602 "LUT table might be ignored during encoding.")
2605 ienc_pnts = (
ui32)enc_pnts;
2606 ienc_pnts = 32 - count_leading_zeros(ienc_pnts);
2607 ienc_pnts = 1u << ienc_pnts;
2608 ienc_pnts =
ojph_max(ienc_pnts, 2);
2620 OJPH_ERROR(0x000501A9,
"Failed to allocated memory");
2633 bool& is_signed,
ui8& nl_type)
const
2637 assert(
Cnlt == special_comp_num::ALL_COMPS);
2639 p = (p && p->
enabled) ? p :
this;
2643 bit_depth = bit_depth <= 38 ? bit_depth : 38;
2644 is_signed = (p->
rec.
BDnlt & 0x80) == 0x80;
2667 buf2 = swap_bytes_if_le(buf2);
2669 buf2 = swap_bytes_if_le(p->
Lnlt);
2671 buf2 = swap_bytes_if_le(p->
Cnlt);
2675 if (p->
rec.
Tnlt == nonlinearity::OJPH_NLT_LUT_STYLE_NLT ||
2676 p->
rec.
Tnlt == nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
2679 buf2 = swap_bytes_if_le(buf2);
2681 buf4 = swap_bytes_if_le(p->
rec.
d_min);
2683 buf4 = swap_bytes_if_le(p->
rec.
d_max);
2690 result &= file->
write(&buf1,
sizeof(
ui8)) ==
sizeof(
ui8);
2700 memcpy(&buf2, sp, 2);
2701 buf2 = swap_bytes_if_le(buf2);
2710 memcpy(&buf4, sp, 4);
2711 buf4 = swap_bytes_if_le(buf4);
2731 result &= file->
read(&buf2_len,
sizeof(
ui16)) ==
sizeof(
ui16);
2732 result &= file->
read(&buf2_comp,
sizeof(
ui16)) ==
sizeof(
ui16);
2733 result &= file->
read(&buf1_BDnlt,
sizeof(
ui8)) ==
sizeof(
ui8);
2734 result &= file->
read(&buf1_Tnlt,
sizeof(
ui8)) ==
sizeof(
ui8);
2735 if (result ==
false)
2736 OJPH_ERROR(0x000501E1,
"Error reading NLT marker, Location 1");
2738 if (buf1_Tnlt != nonlinearity::OJPH_NLT_NO_NLT &&
2739 buf1_Tnlt != nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT &&
2740 buf1_Tnlt != nonlinearity::OJPH_NLT_LUT_STYLE_NLT &&
2741 buf1_Tnlt != nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
2742 OJPH_ERROR(0x00050141,
"Unsupported nonlinearity type in an "
2743 "NLT marker segment, with a value of", buf1_Tnlt);
2745 ui16 length = swap_bytes_if_le(buf2_len);
2746 if (buf1_Tnlt == nonlinearity::OJPH_NLT_NO_NLT ||
2747 buf1_Tnlt == nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT)
2750 OJPH_ERROR(0x00050142,
"Somethins is wrong with this NLT "
2751 "marker segment -- it has an incorrect length of %d",
2755 ui16 comp = swap_bytes_if_le(buf2_comp);
2756 if (comp > 16383 && comp != special_comp_num::ALL_COMPS)
2757 OJPH_ERROR(0x00050143,
"Something is wrong with this NLT "
2758 "marker segment -- it has an incorrect component index of %d",
2767 if ((buf1_BDnlt & 0x7F) + 1 > 38)
2768 OJPH_ERROR(0x00050144,
"The NLT marker segment has an invalid bit "
2769 "depth of %d", (buf1_BDnlt & 0x7F) + 1);
2772 if (buf1_Tnlt == nonlinearity::OJPH_NLT_LUT_STYLE_NLT ||
2773 buf1_Tnlt == nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT)
2775 ui16 buf2_num_points;
2776 ui32 buf4_d_min, buf4_d_max;
2779 result &= file->
read(&buf2_num_points,
sizeof(
ui16)) ==
sizeof(
ui16);
2780 result &= file->
read(&buf4_d_min,
sizeof(
ui32)) ==
sizeof(
ui32);
2781 result &= file->
read(&buf4_d_max,
sizeof(
ui32)) ==
sizeof(
ui32);
2782 result &= file->
read(&buf_pt_val,
sizeof(
ui8)) ==
sizeof(
ui8);
2783 if (result ==
false)
2784 OJPH_ERROR(0x000501E2,
"Error reading NLT marker, Location 2");
2786 buf2_num_points = swap_bytes_if_le(buf2_num_points);
2787 buf4_d_min = swap_bytes_if_le(buf4_d_min);
2788 buf4_d_max = swap_bytes_if_le(buf4_d_max);
2790 if (buf2_num_points < 1 || buf2_num_points > 8191)
2791 OJPH_ERROR(0x00050145,
"The NLT marker segment has an invalid "
2792 "number of points field", buf2_num_points);
2793 if (buf4_d_min >= buf4_d_max)
2794 OJPH_ERROR(0x00050146,
"In an NLT marker segment, Dmin must smaller "
2795 "than Dmax; here we have %d and %d", buf4_d_min, buf4_d_max);
2796 if (buf_pt_val == 0 || buf_pt_val > 32)
2797 OJPH_ERROR(0x00050147,
"In an NLT marker segment, the value of "
2798 "pt_val must be larger than 0 and smaller or equal to 32; "
2799 "here, we have %d", buf_pt_val);
2816 OJPH_ERROR(0x00050148,
"Failed to allocated memory");
2831 result &= file->
read(&buf2,
sizeof(
ui16)) ==
sizeof(
ui16);
2832 buf2 = swap_bytes_if_le(buf2);
2833 memcpy(dp, &buf2, 2);
2842 result &= file->
read(&buf4,
sizeof(
ui32)) ==
sizeof(
ui32);
2843 buf4 = swap_bytes_if_le(buf4);
2844 memcpy(dp, &buf4, 4);
2850 if (result ==
false)
2851 OJPH_ERROR(0x000501E3,
"Error reading NLT marker, Location 3");
2859 assert(
Cnlt == special_comp_num::ALL_COMPS);
2883 assert(
Cnlt == special_comp_num::ALL_COMPS);
2886 while (p && p->
Cnlt != comp_num)
2894 assert(comp_num != special_comp_num::ALL_COMPS);
2895 assert(
Cnlt == special_comp_num::ALL_COMPS);
2897 while (p->
next != NULL) {
2898 assert(p->
Cnlt != comp_num);
2919 while (p && p->
enabled ==
false)
2931 OJPH_INFO(0x00050161,
"The NLT marker segment for the "
2932 "non-existing component %d has been removed.", p->
Cnlt);
2954 this->
Psot = payload_len + 14;
2957 buf2 = swap_bytes_if_le(buf2);
2959 buf2 = swap_bytes_if_le(
Lsot);
2961 buf2 = swap_bytes_if_le(
Isot);
2963 buf4 = swap_bytes_if_le(
Psot);
2980 buf2 = swap_bytes_if_le(buf2);
2982 buf2 = swap_bytes_if_le(
Lsot);
2984 buf2 = swap_bytes_if_le(
Isot);
2986 buf4 = swap_bytes_if_le(payload_len + 14);
3001 OJPH_INFO(0x00050091,
"error reading SOT marker");
3008 OJPH_INFO(0x00050092,
"error in SOT length");
3014 OJPH_INFO(0x00050093,
"error reading tile index");
3021 OJPH_INFO(0x00050094,
"tile index in SOT marker cannot be 0xFFFF");
3027 OJPH_INFO(0x00050095,
"error reading SOT marker");
3034 OJPH_INFO(0x00050096,
"error reading SOT marker");
3040 OJPH_INFO(0x00050097,
"error reading SOT marker");
3048 OJPH_ERROR(0x00050091,
"error reading SOT marker");
3051 OJPH_ERROR(0x00050092,
"error in SOT length");
3053 OJPH_ERROR(0x00050093,
"error reading SOT tile index");
3056 OJPH_ERROR(0x00050094,
"tile index in SOT marker cannot be 0xFFFF");
3058 OJPH_ERROR(0x00050095,
"error reading SOT marker");
3061 OJPH_ERROR(0x00050096,
"error reading SOT marker");
3063 OJPH_ERROR(0x00050097,
"error reading SOT marker");
3080 OJPH_ERROR(0x000500B1,
"Trying to store %d tileparts in TLM markers, "
3081 "but at most %d can be indexed; a codestream can carry "
3082 "%d TLM marker segments of %d entries each.",
3116 buf2 = swap_bytes_if_le(buf2);
3118 buf2 = swap_bytes_if_le((
ui16)(4 + 6 * count));
3120 result &= file->
write(&Ztlm, 1) == 1;
3121 result &= file->
write(&Stlm, 1) == 1;
3122 for (
ui32 i = written; i < written + count; ++i)
3124 buf2 = swap_bytes_if_le(
pairs[i].Ttlm);
3126 buf4 = swap_bytes_if_le(
pairs[i].Ptlm);
3147 while (p && p->
Sdfs != index)
3156 ui32 d = decomp_level - 1;
3158 ui32 bits = d & 0x3;
3159 ui32 val = (
Ddfs[idx] >> (6 - 2 * bits)) & 0x3;
3170 ui32 ns[4] = { 0, 3, 1, 1 };
3192 ui32 decomp_level = 1;
3193 while (skipped_resolutions > 0)
3197 { factor.
x *= 2; factor.
y *= 2; }
3204 --skipped_resolutions;
3214 while (p->
next != NULL)
3225 return p->
read(file);
3229 OJPH_ERROR(0x000500D1,
"error reading DFS-Ldfs parameter");
3232 OJPH_ERROR(0x000500D2,
"error reading DFS-Sdfs parameter");
3235 OJPH_ERROR(0x000500D3,
"The DFS-Sdfs parameter is %d, which is "
3236 "larger than the permissible 15",
Sdfs);
3238 if (file->
read(&l_Ids, 1) != 1)
3239 OJPH_ERROR(0x000500D4,
"error reading DFS-Ids parameter");
3242 "The value of the Ids member in the DFS marker segment cannot be 0");
3243 constexpr int max_Ddfs =
sizeof(
Ddfs) * 4;
3244 if (l_Ids > max_Ddfs)
3245 OJPH_INFO(0x000500D5,
"The DFS-Ids parameter is %d; while this is "
3246 "valid, the number is unnessarily large -- you do not need more "
3247 "than %d. Please contact me regarding this issue.",
3249 Ids = l_Ids < max_Ddfs ? l_Ids : max_Ddfs;
3250 for (
int i = 0; i <
Ids; i += 4)
3251 if (file->
read(&
Ddfs[i / 4], 1) != 1)
3252 OJPH_ERROR(0x000500D6,
"error reading DFS-Ddfs parameters");
3253 for (
int i =
Ids; i < l_Ids; i += 4)
3254 if (file->
read(&t, 1) != 1)
3255 OJPH_ERROR(0x000500D7,
"error reading DFS-Ddfs parameters");
3278 if (index == 0) { this->
init_irv97();
return this; }
3279 else if (index == 1) { this->
init_rev53();
return this; }
3286 if (p == NULL && (index == 0 || index == 1))
3293 else if (index == 1)
3304 if (coeff_type == 0) {
3306 if (file->
read(&v, 1) != 1)
return false;
3310 else if (coeff_type == 1) {
3312 if (file->
read(&v, 2) != 2)
return false;
3314 K = swap_bytes_if_le(v);
3316 else if (coeff_type == 2) {
3318 if (file->
read(&i,
sizeof(
ui32)) !=
sizeof(
ui32))
return false;
3320 i = swap_bytes_if_le(i);
3322 memcpy(&f, &i,
sizeof(
float));
3325 else if (coeff_type == 3) {
3327 if (file->
read(&i,
sizeof(
ui64)) !=
sizeof(
ui64))
return false;
3329 i = swap_bytes_if_le(i);
3331 memcpy(&
d, &i,
sizeof(
double));
3334 else if (coeff_type == 4) {
3336 if (file->
read(&v, 8) != 8)
return false;
3338 if (file->
read(&v1, 8) != 8)
return false;
3340 v = swap_bytes_if_le(v);
3345 si32 e = (
si32)((v >> 48) & 0x7FFF);
3351 i |= ((
ui32)(v >> 32) & 0x80000000);
3353 i |= (
ui32)((v >> 25) & 0x007FFFFF);
3355 memcpy(&f, &i,
sizeof(
float));
3366 if (coeff_type == 0) {
3368 if (file->
read(&v, 1) != 1)
return false;
3372 else if (coeff_type == 1) {
3374 if (file->
read(&v, 2) != 2)
return false;
3376 K = (
si16)swap_bytes_if_le((
ui16)v);
3390 OJPH_ERROR(0x000500E1,
"error reading ATK-Latk parameter");
3394 if (file->
read(&temp_Satk, 2) != 2)
3395 OJPH_ERROR(0x000500E2,
"error reading ATK-Satk parameter");
3397 temp_Satk = swap_bytes_if_le(temp_Satk);
3398 int tmp_idx = temp_Satk & 0xFF;
3400 || tmp_idx == 0 || tmp_idx == 1)
3401 OJPH_ERROR(0x000500F3,
"ATK-Satk parameter sets ATK marker index to "
3402 "the illegal value of %d. ATK-Satk should be in (2-255) and, I "
3403 "believe, must not be repeated; otherwise, it would be unclear "
3404 "what marker segment must be employed when an index is repeated.",
3408 OJPH_ERROR(0x000500E3,
"ATK-Satk parameter sets m_init to 1, "
3409 "requiring odd-indexed subsequence in first reconstruction step, "
3410 "which is not supported yet.");
3412 OJPH_ERROR(0x000500E4,
"ATK-Satk parameter specified ARB filter, "
3413 "which is not supported yet.");
3415 OJPH_ERROR(0x000500E5,
"ATK-Satk parameter does not make sense. "
3416 "It employs floats with reversible filtering.");
3418 OJPH_ERROR(0x000500E6,
"ATK-Satk parameter requires constant "
3419 "boundary extension, which is not supported yet.");
3422 OJPH_ERROR(0x000500E7,
"error reading ATK-Katk parameter");
3424 OJPH_ERROR(0x000500E8,
"error reading ATK-Natk parameter");
3435 for (
int s = 0; s <
Natk; ++s)
3438 OJPH_ERROR(0x000500E9,
"error reading ATK-Eatk parameter");
3441 OJPH_ERROR(0x000500EA,
"error reading ATK-Batk parameter");
3445 if (file->
read(&LCatk, 1) != 1)
3446 OJPH_ERROR(0x000500EB,
"error reading ATK-LCatk parameter");
3449 OJPH_ERROR(0x000500EC,
"Encountered a ATK-LCatk value of zero; "
3450 "something is wrong.");
3452 OJPH_ERROR(0x000500ED,
"ATK-LCatk value greater than 1; "
3453 "that is, a multitap filter is not supported");
3455 OJPH_ERROR(0x000500EE,
"Error reding ATK-Aatk parameter");
3460 for (
int s = 0; s <
Natk; ++s)
3463 if (file->
read(&LCatk, 1) != 1)
3464 OJPH_ERROR(0x000500EF,
"error reading ATK-LCatk parameter");
3467 OJPH_ERROR(0x000500F0,
"Encountered a ATK-LCatk value of zero; "
3468 "something is wrong.");
3470 OJPH_ERROR(0x000500F1,
"ATK-LCatk value greater than 1; "
3471 "that is, a multitap filter is not supported.");
3473 OJPH_ERROR(0x000500F2,
"Error reding ATK-Aatk parameter");
3477 OJPH_ERROR(0x000500F3,
"The length of an ATK marker segment "
3478 "(ATK-Latk) is not correct");
3487 Katk = (float)1.230174104914001;
3491 d[0].
irv.
Aatk = (float)0.443506852043971;
3492 d[1].
irv.
Aatk = (float)0.882911075530934;
3493 d[2].
irv.
Aatk = (float)-0.052980118572961;
3494 d[3].
irv.
Aatk = (float)-1.586134342059924;
3517 while (p->
next != NULL)
virtual size_t read(void *ptr, size_t size)=0
static const float gain_5x3_l[34]
static float get_bibo_gain_l(ui32 num_decomp, bool reversible)
static const float gain_5x3_h[34]
static float get_bibo_gain_h(ui32 num_decomp, bool reversible)
static const float gain_9x7_h[34]
static const float gain_9x7_l[34]
static const float gain_5x3_l[34]
static const float gain_5x3_h[34]
static float get_gain_l(ui32 num_decomp, bool reversible)
static const float gain_9x7_l[34]
static float get_gain_h(ui32 num_decomp, bool reversible)
static const float gain_9x7_h[34]
static const float * get_weights(ui32 format, ui32 comp_type)
static const float no_weights[19]
static const float * get_no_weights()
static const float cr444[19]
static const float cb422[19]
static const float cr422[19]
static const float cb420[19]
static float get_delta_ref(float qfactor, ui32 bit_depth, float &power)
static const float cr420[19]
static colour_format get_format(const point &component_subsampling)
static const float cb444[19]
param_qcd::comp_type comp_type
static float get_weight(const float *v, ui32 decomposition_level, ui32 subband_idx)
static float get_gain(ui32 comp_type)
virtual size_t write(const void *ptr, size_t size)=0
size get_block_dims() const
int get_progression_order() const
bool is_using_color_transform() const
void set_num_decomposition(ui32 num_decompositions)
ui32 get_num_decompositions() const
size get_log_block_dims() const
bool packets_may_use_sop() const
size get_precinct_size(ui32 level_num) const
const char * get_progression_order_as_string() const
void set_precinct_size(int num_levels, size *precinct_size)
bool packets_use_eph() const
bool is_reversible() const
void set_progression_order(const char *name)
bool get_block_vertical_causality() const
void set_block_dims(ui32 width, ui32 height)
size get_log_precinct_size(ui32 level_num) const
int get_num_layers() const
void set_color_transform(bool color_transform)
void set_reversible(bool reversible)
@ OJPH_NLT_BINARY_COMPLEMENT_NLT
@ OJPH_NLT_BINARY_COMPLEMENT_PLUS_LUT
bool get_nonlinear_transform(ui32 comp_num, ui8 &decoded_bit_depth, bool &decoded_signedness, ui8 &nl_type) const
void set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
void set_qfactor(float qfactor)
Sets Qfactor.
void set_irrev_quant(float delta)
Set the irreversible quantization base delta.
static comp_type ui8_2_comp_type(ui8 c)
void set_tile_size(size s)
point get_image_extent() const
void set_component(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
void set_num_components(ui32 num_comps)
ui32 get_bit_depth(ui32 comp_num) const
void set_tile_offset(point offset)
point get_image_offset() const
void set_image_offset(point offset)
size get_tile_size() const
ui32 get_recon_height(ui32 comp_num) const
point get_downsampling(ui32 comp_num) const
void set_image_extent(point extent)
point get_tile_offset() const
ui32 get_recon_width(ui32 comp_num) const
bool is_signed(ui32 comp_num) const
ui32 get_num_components() const
static void prepare_for_encoding_approx_for_type(const void *marker_points, float div, float &ft_min, float &ft_max, float &delta, float &inv_delta, float fd_min, float fd_max, ui32 num_points, ui32 enc_num_points, float *approx_enc_points)
const char OJPH_PO_STRING_PCRL[]
const char OJPH_PO_STRING_RLCP[]
const char OJPH_PO_STRING_RPCL[]
const char OJPH_PO_STRING_CPRL[]
const char OJPH_PO_STRING_LRCP[]
int main(int argc, char *argv[])
#define ojph_div_ceil(a, b)
#define OJPH_INFO(t,...)
MACROs to insert file and line number for info, warning, and error.
#define OJPH_ERROR(t,...)
ui32 cal_store_size_for_encoding(ui32 enc_num_points)
void assign_pointers_for_decoding()
ui32 cal_store_size_for_decoding()
void prepare_for_encoding_precise()
void prepare_for_decoding()
ui8 get_bit_depth() const
void prepare_for_encoding()
ui16 * precise_enc_dec_indices
void assign_pointers_for_encoding()
float * approx_enc_points
static ui8 get_bpp(ui32 t)
void prepare_for_encoding_approx()
bool read_coefficient(infile_base *file, float &K, si32 &bytes)
void init(param_atk *top_atk)
bool is_reversible() const
bool read(infile_base *file)
int get_coeff_type() const
param_atk * get_atk(int index)
bool is_whole_sample() const
bool is_using_ws_extension() const
void read(infile_base *file)
bool write(outfile_base *file)
bool write(outfile_base *file)
size get_block_dims() const
const param_cod * get_coc(ui32 comp_idx) const
bool internal_write_coc(outfile_base *file, ui32 num_comps)
size get_log_block_dims() const
ui16 get_dfs_index() const
bool write_coc(outfile_base *file, ui32 num_comps)
void set_reversible(bool reversible)
bool is_employing_color_transform() const
void employ_color_transform(ui8 val)
ui32 get_comp_idx() const
bool get_block_vertical_causality() const
void read(infile_base *file)
size get_log_precinct_size(ui32 res_num) const
void init(param_cod *top_cod, ui16 comp_idx)
void read_coc(infile_base *file, ui32 num_comps, param_cod *top_cod)
void update_atk(param_atk *atk)
bool is_dfs_defined() const
bool packets_use_eph() const
ui8 get_num_decompositions() const
bool packets_may_use_sop() const
bool is_reversible() const
size get_precinct_size(ui32 res_num) const
param_cod * get_or_add_coc(ui32 comp_idx)
param_cod(param_cod *top_cod=NULL, ui16 comp_idx=OJPH_COD_DEFAULT)
ui8 get_wavelet_kern() const
param_cod * add_coc_object(ui32 comp_idx)
bool read(infile_base *file)
dfs_dwt_type get_dwt_type(ui32 decomp_level) const
point get_res_downsamp(ui32 skipped_resolutions) const
ui32 get_subband_idx(ui32 num_decompositions, ui32 resolution, ui32 subband) const
const param_dfs * get_dfs(int index) const
bool write(outfile_base *file) const
param_nlt * add_object(ui32 comp_num)
void trim_non_existing_components(ui32 num_comps)
ojph::param_nlt::nonlinearity nonlinearity
void check_validity(param_siz &siz, const param_cod &cod)
const param_nlt * get_nlt_object(ui32 comp_num) const
bool read(infile_base *file)
int find_unsupported_nlt(const param_siz &siz, const param_cod &cod) const
bool is_any_enabled() const
void set_nonlinear_transform(ui32 comp_num, ui8 nl_type)
const nlt_rec * get_nlt_rec(ui32 comp_num) const
bool get_nonlinear_transform(ui32 comp_num, ui8 &decoded_bit_depth, bool &decoded_signedness, ui8 &nl_type) const
const float QFACTOR_UNSET
bool write_qcc(outfile_base *file, ui32 num_comps)
float get_irrev_delta(const param_dfs *dfs, ui32 num_decompositions, ui32 comp_num, ui32 resolution, ui32 subband) const
void set_rev_quant(ui32 num_decomps, ui32 bit_depth, bool is_employing_color_transform)
void set_irrev_quant(ui32 num_decomps)
ui32 get_largest_Kmax() const
ui32 get_num_guard_bits() const
void set_delta(float delta)
void read_qcc(infile_base *file, ui32 num_comps)
void check_validity(const param_siz &siz, const param_cod &cod)
bool write(outfile_base *file)
ui32 propose_precision(const param_cod *cod) const
void read(infile_base *file)
bool is_qcc_needed(ui32 comp_num, const param_cod &cod, const param_siz &siz)
void make_quant_steps(ui32 comp_num, const param_cod &cod, const param_siz &siz)
void init(param_qcd *top_qcd, ui16 comp_idx)
param_qcd * add_qcc_object(ui32 comp_idx)
ui32 get_Kmax(const param_dfs *dfs, ui32 num_decompositions, ui32 resolution, ui32 subband) const
void set_weights(size_t num_weights, const float *weights)
ojph::param_qcd::comp_type comp_type
void encode_SPqcd(ui32 subband_index, float delta)
ui8 decode_SPqcd(ui8 v) const
param_qcd * get_qcc(ui32 comp_idx)
param_qcd(param_qcd *top_qcd=NULL, ui16 comp_idx=OJPH_QCD_DEFAULT)
static constexpr ui32 MAX_SUBBAND_COUNT
void trim_non_existing_components(ui32 num_comps)
void set_qfactor(float qfactor)
bool internal_write_qcc(outfile_base *file, ui32 num_comps)
union ojph::local::param_qcd::@140013103227173134364232343330020031205064137337 SPqcd
float weights[MAX_SUBBAND_COUNT]
ui32 get_bit_depth(ui32 comp_num) const
bool ws_kern_support_needed
ui32 get_recon_height(ui32 comp_num) const
bool is_signed(ui32 comp_num) const
void set_image_offset(point offset)
bool write(outfile_base *file)
ui16 get_num_components() const
void set_tile_size(size s)
point get_recon_downsampling(ui32 comp_num) const
void set_Rsiz_flag(ui16 flag)
point get_recon_size(ui32 comp_num) const
void set_comp_info(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
point get_downsampling(ui32 comp_num) const
void set_tile_offset(point offset)
void read(infile_base *file)
void set_num_components(ui32 num_comps)
void set_image_extent(point dims)
ui32 get_recon_width(ui32 comp_num) const
bool read(infile_base *file, bool resilient)
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)
point(ui32 x=0, ui32 y=0)