71#include "gtest/gtest.h"
76#define REF_FILE_DIR ".\\jp2k_test_codestreams\\openjph\\references\\"
77#define OUT_FILE_DIR ".\\"
79#define REF_FILE_DIR "./jp2k_test_codestreams/openjph/references/"
80#define OUT_FILE_DIR "./"
85#define NLT_MARKER_HIGH 0xFF
86#define NLT_MARKER_LOW 0x76
97 const ui32 pfmLutNumPoints = 152;
98 const ui32 pfmLutDmin = 67109888;
99 const ui32 pfmLutDmax = 4227857408;
100 const ui32 pfmLutPoints[pfmLutNumPoints] = {
101 67109888, 88737098, 106890847, 122160968, 135661590, 157092189,
102 175049327, 190122837, 204213292, 225447280, 243207807, 258084706,
103 272764994, 293736834, 311300750, 326046575, 341316696, 362026388,
104 379393693, 394008444, 409802861, 430315942, 447486636, 461904776,
105 478289026, 498605496, 515579579, 529866645, 546775191, 566829513,
106 583672522, 597762977, 615261356, 635053530, 651699928, 665659309,
107 683681984, 703343084, 719792871, 733555641, 752102612, 771501564,
108 787820277, 801451973, 820523240, 839725581, 855847683, 869348305,
109 888943868, 907949598, 923875089, 937179100, 957364496, 976108078,
110 991836958, 1005075432, 1025719587, 1044266558, 1059864364, 1072906227,
111 1094074678, 1112425038, 1127891770, 1140802559, 1163281750, 1183532683,
112 1201620895, 1227180325, 1254836939, 1281838183, 1321029309, 1362907452,
113 1412912183, 1485985938, 1596677931, 1830579484, 2464387812, 2698289365,
114 2808981358, 2882055113, 2932059844, 2973937987, 3013129113, 3040130357,
115 3067786971, 3093346401, 3111434613, 3131685546, 3154164737, 3167075526,
116 3182542258, 3200892618, 3222061069, 3235102932, 3250700738, 3269247709,
117 3289891864, 3303130338, 3318859218, 3337602800, 3357788196, 3371092207,
118 3387017698, 3406023428, 3425618991, 3439119613, 3455241715, 3474444056,
119 3493515323, 3507147019, 3523465732, 3542864684, 3561411655, 3575174425,
120 3591624212, 3611285312, 3629307987, 3643267368, 3659913766, 3679705940,
121 3697204319, 3711294774, 3728137783, 3748192105, 3765100651, 3779387717,
122 3796361800, 3816678270, 3833062520, 3847480660, 3864651354, 3885164435,
123 3900958852, 3915573603, 3932940908, 3953650600, 3968920721, 3983666546,
124 4001230462, 4022202302, 4036882590, 4051759489, 4069520016, 4090754004,
125 4104844459, 4119917969, 4137875107, 4159305706, 4172806328, 4188076449,
126 4206230198, 4227857408};
134 const ui32 identityLutNumPoints = 129;
135 ui32 identityLutPoints[identityLutNumPoints];
136 bool identityLutReady =
false;
138 void prepare_identity_lut()
140 if (identityLutReady)
142 for (
ui32 i = 0; i < identityLutNumPoints; ++i)
143 identityLutPoints[i] =
144 (
ui32)(((double)i / (identityLutNumPoints - 1)) * 4294967295.0);
145 identityLutReady =
true;
155 ui32 width = 0, height = 0, num_comps = 0;
156 std::vector<std::vector<si32> > samples;
158 size_t num_samples()
const
159 {
return (
size_t)width * height * num_comps; }
167 long long max_abs_error = 0;
168 double mean_abs_error = 0.0;
169 double max_rel_error = 0.0;
170 double mean_rel_error = 0.0;
171 size_t num_bit_exact = 0;
172 size_t num_samples = 0;
174 bool is_bit_exact()
const {
return num_bit_exact == num_samples; }
182 bool load_pfm(
const std::string& filename, test_image& img)
184 FILE* f = fopen(filename.c_str(),
"rb");
188 char magic[3] = { 0, 0, 0 };
189 if (fscanf(f,
"%2s", magic) != 1 ||
190 (magic[1] !=
'f' && magic[1] !=
'F'))
198 if (fscanf(f,
"%d %d %f", &w, &h, &scale) != 3 || w <= 0 || h <= 0)
210 const bool file_little_endian = scale < 0.0f;
214 img.height = (
ui32)h;
215 img.num_comps = magic[1] ==
'f' ? 1 : 3;
216 img.samples.assign(img.num_comps,
217 std::vector<si32>((
size_t)w * (
size_t)h, 0));
219 std::vector<ui32> line((
size_t)w * img.num_comps, 0);
220 for (
int y = h - 1; y >= 0; --y)
222 if (fread(&line[0],
sizeof(
ui32), (
size_t)w * img.num_comps, f)
223 != (
size_t)w * img.num_comps)
228 for (
int x = 0; x < w; ++x)
229 for (
ui32 c = 0; c < img.num_comps; ++c)
231 ui32 u = line[(size_t)x * img.num_comps + c];
233 u = (u >> 24) | ((u >> 8) & 0x0000FF00u) |
234 ((u << 8) & 0x00FF0000u) | (u << 24);
235 img.samples[c][(size_t)y * (
size_t)w + (size_t)x] = (
si32)u;
250 std::string find_test_image(
const std::string& name)
253 for (
size_t i = 0; i <
sizeof(dirs) /
sizeof(dirs[0]); ++i)
255 std::string path = std::string(dirs[i]) + name;
256 FILE* f = fopen(path.c_str(),
"rb");
263 return std::string();
271 const char*
const image_names[2] = {
"random.pfm",
"rgb.pfm" };
272 const size_t num_images =
sizeof(image_names) /
sizeof(image_names[0]);
277 std::string load_test_images(test_image images[num_images])
280 for (
size_t i = 0; i < num_images; ++i)
282 std::string path = find_test_image(image_names[i]);
283 if (path.empty() || !load_pfm(path, images[i]))
285 if (!missing.empty())
287 missing += image_names[i];
310 void make_synthetic_image(test_image& img,
ui32 width,
ui32 height)
315 img.samples.assign(1, std::vector<si32>((
size_t)width * height, 0));
319 const si64 lowest = -2070000000LL;
320 const si64 highest = 2070000000LL;
321 const si64 gap = 1LL << 20;
322 const si64 half = (
si64)((
size_t)width * height / 2);
323 std::vector<si32>& s = img.samples[0];
324 for (
size_t i = 0; i < s.size(); ++i)
326 if (i < (
size_t)half)
327 s[i] = (
si32)(gap + (highest - gap) * (
si64)i / (half - 1));
330 (lowest + gap) * (
si64)(i - (
size_t)half) / (half - 1));
351 float default_qstep() {
return 1.0f / 16384.0f; }
356 void apply_nlt(
codestream& cs,
const nlt_setting& setting)
367 ui32 d_min, d_max, num_points;
369 if (setting.use_pfm_lut)
373 num_points = pfmLutNumPoints;
374 points = (
void*)pfmLutPoints;
378 prepare_identity_lut();
381 num_points = identityLutNumPoints;
382 points = (
void*)identityLutPoints;
385 d_min, d_max, 32, (
ui16)num_points, points, setting.type);
392 void encode_image(
const std::string& filename,
const test_image& img,
393 const nlt_setting& setting)
400 for (
ui32 c = 0; c < img.num_comps; ++c)
411 if (!setting.reversible)
414 apply_nlt(cs, setting);
419 file.
open(filename.c_str());
424 ASSERT_TRUE(cur_line != NULL) << filename;
425 for (
ui32 c = 0; c < img.num_comps; ++c)
426 for (
ui32 y = 0; y < img.height; ++y)
428 ASSERT_EQ(next_comp, c) << filename;
429 for (
ui32 x = 0; x < img.width; ++x)
430 cur_line->i32[x] = img.samples[c][(
size_t)y * img.width + x];
431 cur_line = cs.
exchange(cur_line, next_comp);
441 void decode_image(
const std::string& filename, test_image& img,
442 bool* has_nlt,
ui8* nlt_type,
ui8* nlt_bit_depth,
447 file.
open(filename.c_str());
450 if (has_nlt != NULL || nlt_type != NULL || nlt_bit_depth != NULL ||
451 nlt_is_signed != NULL)
453 ui8 bit_depth = 0, type = 0;
454 bool is_signed =
false;
457 if (has_nlt != NULL) *has_nlt = found;
458 if (nlt_type != NULL) *nlt_type = type;
459 if (nlt_bit_depth != NULL) *nlt_bit_depth = bit_depth;
460 if (nlt_is_signed != NULL) *nlt_is_signed = is_signed;
467 img.samples.assign(img.num_comps,
468 std::vector<si32>((
size_t)img.width * img.height, 0));
474 for (
ui32 c = 0; c < img.num_comps; ++c)
475 for (
ui32 y = 0; y < img.height; ++y)
479 ASSERT_TRUE(line != NULL) << filename;
480 ASSERT_EQ(comp_num, c) << filename;
481 for (
ui32 x = 0; x < img.width; ++x)
482 img.samples[c][(
size_t)y * img.width + x] = line->i32[x];
493 comparison compare_images(
const test_image& before,
const test_image& after)
498 for (
ui32 c = 0; c < before.num_comps; ++c)
499 for (
size_t i = 0; i < before.samples[c].size(); ++i)
502 memcpy(&v, &before.samples[c][i],
sizeof(
float));
503 peak = std::max(peak, (
double)fabs(v));
507 const double floor = std::max(peak * 1e-5, 1e-30);
509 double sum_abs = 0.0, sum_rel = 0.0;
510 for (
ui32 c = 0; c < before.num_comps; ++c)
511 for (
size_t i = 0; i < before.samples[c].size(); ++i)
513 si32 a = before.samples[c][i], b = after.samples[c][i];
517 result.max_abs_error = std::max(result.max_abs_error, (
long long)err);
518 sum_abs += (double)err;
521 memcpy(&av, &a,
sizeof(
float));
522 memcpy(&bv, &b,
sizeof(
float));
523 double rel = fabs((
double)av - (
double)bv) /
524 std::max((
double)fabs(av), floor);
525 result.max_rel_error = std::max(result.max_rel_error, rel);
529 ++result.num_bit_exact;
530 ++result.num_samples;
533 result.mean_abs_error = sum_abs / (double)result.num_samples;
534 result.mean_rel_error = sum_rel / (double)result.num_samples;
542 comparison round_trip(
const std::string& tag,
const test_image& img,
543 const nlt_setting& setting)
545 const std::string filename = std::string(
OUT_FILE_DIR) + tag +
".j2c";
546 encode_image(filename, img, setting);
549 decode_image(filename, decoded, NULL, NULL, NULL, NULL);
551 EXPECT_EQ(decoded.width, img.width) << tag;
552 EXPECT_EQ(decoded.height, img.height) << tag;
553 EXPECT_EQ(decoded.num_comps, img.num_comps) << tag;
555 return compare_images(img, decoded);
561 bool has_nlt_marker(
const std::string& filename)
563 FILE* f = fopen(filename.c_str(),
"rb");
569 while ((cur = fgetc(f)) != EOF)
588 int num_messages = 0;
591 virtual void operator() (
int warn_code,
const char* file_name,
592 int line_num,
const char* fmt, ...)
598 last_code = warn_code;
604 int num_messages = 0;
607 virtual void operator() (
int error_code,
const char* file_name,
608 int line_num,
const char* fmt, ...)
614 last_code = error_code;
615 throw std::runtime_error(
"ojph error");
619 struct message_capture
621 warning_collector warnings;
622 error_collector errors;
647 bool insert_lut_nlt_marker(
const std::string& filename,
ui8 nlt_type)
649 FILE* f = fopen(filename.c_str(),
"rb");
653 std::vector<ui8> data;
656 while ((num_read = fread(buffer, 1,
sizeof(buffer), f)) > 0)
657 data.insert(data.end(), buffer, buffer + num_read);
661 size_t sot = data.size();
662 for (
size_t i = 0; i + 1 < data.size(); ++i)
663 if (data[i] == 0xFF && data[i + 1] == 0x90)
668 if (sot == data.size())
671 const ui16 num_points = 17;
672 const ui32 d_min = 0, d_max = 0xFFFFFFFFu;
673 const ui32 length = 17u + 4u * (
ui32)num_points;
675 std::vector<ui8> marker;
676 marker.push_back(0xFF);
677 marker.push_back(0x76);
678 marker.push_back((
ui8)(length >> 8));
679 marker.push_back((
ui8)(length & 0xFF));
680 marker.push_back(0xFF);
681 marker.push_back(0xFF);
682 marker.push_back(0x9F);
683 marker.push_back(nlt_type);
684 marker.push_back((
ui8)((num_points - 1) >> 8));
685 marker.push_back((
ui8)((num_points - 1) & 0xFF));
686 for (
int i = 3; i >= 0; --i)
687 marker.push_back((
ui8)(d_min >> (8 * i)));
688 for (
int i = 3; i >= 0; --i)
689 marker.push_back((
ui8)(d_max >> (8 * i)));
690 marker.push_back(32);
691 for (
ui32 i = 0; i < (
ui32)num_points; ++i)
694 (
ui32)(((
double)i / (num_points - 1)) * 4294967295.0);
695 for (
int b = 3; b >= 0; --b)
696 marker.push_back((
ui8)(
point >> (8 * b)));
699 data.insert(data.begin() + (
long)sot, marker.begin(), marker.end());
701 f = fopen(filename.c_str(),
"wb");
704 bool ok = fwrite(&data[0], 1, data.size(), f) == data.size();
715 void encode_two_component_image(
const std::string& filename,
716 const test_image& img,
ui32 nlt_comp)
723 for (
ui32 c = 0; c < 2; ++c)
738 pfmLutDmin, pfmLutDmax, 32, (
ui16)pfmLutNumPoints, (
void*)pfmLutPoints,
744 file.
open(filename.c_str());
749 ASSERT_TRUE(cur_line != NULL) << filename;
750 for (
ui32 c = 0; c < 2; ++c)
751 for (
ui32 y = 0; y < img.height; ++y)
753 ASSERT_EQ(next_comp, c) << filename;
754 for (
ui32 x = 0; x < img.width; ++x)
755 cur_line->i32[x] = img.samples[0][(
size_t)y * img.width + x];
756 cur_line = cs.
exchange(cur_line, next_comp);
770TEST(NltTest, MarkerSegmentRoundTrip)
773 make_synthetic_image(img, 64, 64);
778 for (
size_t i = 0; i < 3; ++i)
781 setting.type = types[i];
782 setting.use_pfm_lut =
true;
783 setting.reversible =
false;
784 setting.qstep = default_qstep();
786 const std::string filename =
OUT_FILE_DIR "nlt_marker.j2c";
787 encode_image(filename, img, setting);
789 bool has_nlt =
false, is_signed =
false;
790 ui8 type = 0, bit_depth = 0;
792 decode_image(filename, decoded, &has_nlt, &type, &bit_depth, &is_signed);
794 EXPECT_TRUE(has_nlt) <<
"nonlinearity " << (int)types[i];
795 EXPECT_EQ((
int)type, (
int)types[i]) <<
"nonlinearity " << (int)types[i];
796 EXPECT_EQ((
int)bit_depth, 32) <<
"nonlinearity " << (int)types[i];
797 EXPECT_TRUE(is_signed) <<
"nonlinearity " << (int)types[i];
798 EXPECT_TRUE(has_nlt_marker(filename)) <<
"nonlinearity " << (int)types[i];
807TEST(NltTest, NoMarkerSegmentWithoutNlt)
810 make_synthetic_image(img, 64, 64);
814 setting.use_pfm_lut =
true;
815 setting.reversible =
false;
816 setting.qstep = default_qstep();
818 const std::string filename =
OUT_FILE_DIR "nlt_none.j2c";
819 encode_image(filename, img, setting);
823 decode_image(filename, decoded, &has_nlt, NULL, NULL, NULL);
825 EXPECT_FALSE(has_nlt);
826 EXPECT_FALSE(has_nlt_marker(filename));
837TEST(NltTest, LutStyleWithIdentityLutKeepsSamples)
840 make_synthetic_image(img, 128, 128);
842 nlt_setting baseline;
844 baseline.use_pfm_lut =
false;
845 baseline.reversible =
false;
846 baseline.qstep = 1e-5f;
847 comparison plain = round_trip(
"nlt_identity_plain", img, baseline);
851 for (
size_t i = 0; i < 2; ++i)
853 nlt_setting setting = baseline;
854 setting.type = types[i];
855 const std::string tag =
"nlt_identity_" + std::to_string((
int)types[i]);
856 comparison nlt = round_trip(tag, img, setting);
861 EXPECT_LE(nlt.mean_abs_error, 3.0 * plain.mean_abs_error + 16.0)
862 <<
"nonlinearity " << (int)types[i] <<
": mean absolute error "
863 << nlt.mean_abs_error <<
" against " << plain.mean_abs_error
864 <<
" for a round trip without a nonlinearity";
865 EXPECT_LT(nlt.max_rel_error, 0.01)
866 <<
"nonlinearity " << (int)types[i] <<
" with an identity table";
874TEST(NltTest, BinaryComplementIsLossless)
876 test_image images[num_images];
877 std::string missing = load_test_images(images);
884 for (
size_t i = 0; i < num_images; ++i)
888 setting.use_pfm_lut =
false;
889 setting.reversible =
true;
890 setting.qstep = default_qstep();
892 const std::string tag = std::string(
"nlt_lossless_") + image_names[i];
893 comparison result = round_trip(tag, images[i], setting);
895 EXPECT_TRUE(result.is_bit_exact()) << image_names[i] <<
": "
896 << (result.num_samples - result.num_bit_exact) <<
" of "
897 << result.num_samples <<
" samples changed; the largest change is "
898 << result.max_abs_error <<
" in a 32 bit pattern";
910TEST(NltTest, RoundTripOfTestImages)
912 test_image images[num_images];
913 std::string missing = load_test_images(images);
924 for (
size_t n = 0; n < num_images; ++n)
926 nlt_setting baseline;
928 baseline.use_pfm_lut =
true;
929 baseline.reversible =
false;
930 baseline.qstep = default_qstep();
931 comparison plain = round_trip(std::string(
"nlt_plain_") + image_names[n],
932 images[n], baseline);
934 for (
size_t t = 0; t < 3; ++t)
936 nlt_setting setting = baseline;
937 setting.type = types[t];
938 const std::string tag = std::string(
"nlt_") +
939 std::to_string((
int)types[t]) +
"_" + image_names[n];
940 comparison nlt = round_trip(tag, images[n], setting);
942 std::cout << image_names[n] <<
" with nonlinearity " << (int)types[t]
943 <<
": mean absolute error " << nlt.mean_abs_error
944 <<
", mean relative error " << nlt.mean_rel_error
945 <<
", largest relative error " << nlt.max_rel_error
946 <<
" (without a nonlinearity the mean absolute error is "
947 << plain.mean_abs_error <<
")" << std::endl;
951 const double factor =
954 EXPECT_LE(nlt.mean_abs_error, factor * plain.mean_abs_error + 1024.0)
955 << image_names[n] <<
" with nonlinearity " << (int)types[t]
956 <<
": mean absolute error " << nlt.mean_abs_error <<
" against "
957 << plain.mean_abs_error <<
" for a round trip without a nonlinearity";
958 EXPECT_LT(nlt.mean_rel_error, 0.05)
959 << image_names[n] <<
" with nonlinearity " << (int)types[t];
960 EXPECT_LT(nlt.max_rel_error, 0.30)
961 << image_names[n] <<
" with nonlinearity " << (int)types[t];
972TEST(NltTest, LutStyleIsRejectedWithReversibleWavelet)
975 make_synthetic_image(img, 64, 64);
979 for (
size_t i = 0; i < 2; ++i)
982 setting.type = types[i];
983 setting.use_pfm_lut =
true;
984 setting.reversible =
true;
985 setting.qstep = default_qstep();
987 const std::string filename =
OUT_FILE_DIR "nlt_rejected.j2c";
988 message_capture capture;
989 EXPECT_THROW(encode_image(filename, img, setting), std::runtime_error)
990 <<
"nonlinearity " << (int)types[i] <<
" with the reversible wavelet";
991 EXPECT_EQ(capture.errors.last_code, 0x000501B1)
992 <<
"nonlinearity " << (int)types[i];
999 nlt_setting accepted;
1001 accepted.use_pfm_lut =
true;
1002 accepted.reversible =
false;
1003 accepted.qstep = default_qstep();
1004 EXPECT_NO_THROW(encode_image(
OUT_FILE_DIR "nlt_accepted.j2c", img, accepted));
1011TEST(NltTest, LutStyleIsRejectedPerComponent)
1014 make_synthetic_image(img, 64, 64);
1019 const std::string filename =
OUT_FILE_DIR "nlt_component_accepted.j2c";
1020 EXPECT_NO_THROW(encode_two_component_image(filename, img, 1));
1022 decode_image(filename, decoded, NULL, NULL, NULL, NULL);
1023 EXPECT_EQ(decoded.num_comps, 2u);
1029 const std::string filename =
OUT_FILE_DIR "nlt_component_rejected.j2c";
1030 message_capture capture;
1031 EXPECT_THROW(encode_two_component_image(filename, img, 0),
1032 std::runtime_error);
1033 EXPECT_EQ(capture.errors.last_code, 0x000501B1);
1043TEST(NltTest, LutStyleWithReversibleWaveletIsReportedWhenRead)
1046 make_synthetic_image(img, 64, 64);
1050 nlt_setting setting;
1052 setting.use_pfm_lut =
true;
1053 setting.reversible =
true;
1054 setting.qstep = default_qstep();
1056 const std::string filename =
OUT_FILE_DIR "nlt_foreign.j2c";
1057 encode_image(filename, img, setting);
1058 ASSERT_TRUE(insert_lut_nlt_marker(filename,
1061 message_capture capture;
1064 file.
open(filename.c_str());
1065 EXPECT_THROW(cs.
read_headers(&file), std::runtime_error);
1066 EXPECT_GE(capture.errors.num_messages, 1);
1067 EXPECT_EQ(capture.errors.last_code, 0x00030059);
1069 ui8 bit_depth = 0, type = 0;
1070 bool is_signed =
false;
1072 bit_depth, is_signed, type));
The object represent a codestream.
param_siz access_siz()
Returns the underlying SIZ marker segment object.
param_cod access_cod()
Returns the underlying COD marker segment object.
void restrict_input_resolution(ui32 skipped_res_for_data, ui32 skipped_res_for_recon)
This function restricts resolution decoding for a codestream. It is for a reading (decoding) codestre...
void close()
Call this function to close the underlying file; works for both encoding and decoding codestreams.
void set_planar(bool planar)
Sets the sequence of pushing or pull rows from the machinery.
line_buf * exchange(line_buf *line, ui32 &next_component)
This call is used to send image data rows to the library. We expect to send one row from a single com...
param_qcd access_qcd()
Returns the underlying QCD marker segment object.
void read_headers(infile_base *file)
This call reads the headers of a codestream. It is for a reading (or decoding) codestream,...
void write_headers(outfile_base *file, const comment_exchange *comments=NULL, ui32 num_comments=0)
Writes codestream headers when the codestream is used for writing. This function should be called aft...
void create()
This call is for a decoding (or reading) codestream. Call this function after calling restrict_input_...
param_nlt access_nlt()
Returns the underlying NLT marker segment object.
void flush()
This is the last call to a writing (encoding) codestream. This will write encoded bitstream data to t...
line_buf * pull(ui32 &comp_num)
This call is to pull one row from the codestream, being decoded. The returned line_buf object holds o...
void open(const char *filename)
void open(const char *filename)
Derived from message_base to handle error messages.
Derived from message_base to handle warning messages.
void set_num_decomposition(ui32 num_decompositions)
void set_block_dims(ui32 width, ui32 height)
void set_color_transform(bool color_transform)
void set_reversible(bool reversible)
non-linearity point transformation object (implements NLT marker segment)
@ 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_irrev_quant(float delta)
Set the irreversible quantization base delta.
void set_tile_size(size s)
void set_component(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
void set_num_components(ui32 num_comps)
void set_tile_offset(point offset)
void set_image_offset(point offset)
ui32 get_recon_height(ui32 comp_num) const
void set_image_extent(point extent)
ui32 get_recon_width(ui32 comp_num) const
ui32 get_num_components() const
OJPH_EXPORT message_warning * get_warning()
Get the warning message object, whose operator() member class is called for warning messages – See th...
OJPH_EXPORT void configure_error(message_error *error)
This overrides the default behaviour of handling error messages.
const bool is_machine_little_endian
OJPH_EXPORT message_error * get_error()
Get the error message object, whose operator() member class is called for error messages – See the ma...
OJPH_EXPORT void configure_warning(message_warning *warn)
This overrides the default behaviour of handling warning messages.
point(ui32 x=0, ui32 y=0)
TEST(TestExecutables, OpenJPHCompressNoArguments)