44#include "gtest/gtest.h"
57 const ojph::ui32 MAX_PAIRS_PER_SEG = (65535 - 4) / 6;
67 void scan(
const char* filename, std::vector<tlm_seg>& segs,
68 std::vector<tlm_entry>& entries,
69 std::vector<tile_part>& parts,
size_t& header_end)
71 FILE* f = fopen(filename,
"rb");
72 ASSERT_NE(f, (FILE*)NULL);
73 fseek(f, 0, SEEK_END);
75 fseek(f, 0, SEEK_SET);
76 std::vector<ojph::ui8> b((
size_t)len);
77 size_t got = fread(b.data(), 1, (
size_t)len, f);
79 ASSERT_EQ(got, (
size_t)len);
84 while (pos + 4 <= (
size_t)len)
87 if (marker == 0xFF90) { header_end = pos;
break; }
97 s.count = (
ojph::ui32)(seg_len - 4) / entry_size;
106 e.Ttlm = (e.Ttlm << 8) | p[q + k];
109 for (
ojph::ui32 k = 0; k < (sp ? 4u : 2u); ++k)
110 e.Ptlm = (e.Ptlm << 8) | p[q + k];
112 entries.push_back(e);
115 pos += (size_t)seg_len + 2;
119 while (pos + 12 <= (
size_t)len &&
120 ((p[pos] << 8) | p[pos + 1]) == 0xFF90)
129 size_t end = (size_t)len;
130 if (end >= 2 && ((p[end - 2] << 8) | p[end - 1]) == 0xFFD9)
132 tile_part t = { pos, Isot, (
ojph::ui32)(end - pos) };
136 tile_part t = { pos, Isot, Psot };
146 void expect_entries_describe_tileparts(
const std::vector<tlm_entry>& entries,
147 const std::vector<tile_part>& parts,
150 ASSERT_EQ(entries.size(), parts.size());
151 size_t running = header_end;
152 for (
size_t i = 0; i < entries.size(); ++i)
154 ASSERT_EQ(entries[i].Ttlm, parts[i].Isot) <<
"entry " << i;
155 ASSERT_EQ(entries[i].Ptlm, parts[i].length) <<
"entry " << i;
156 ASSERT_EQ(running, parts[i].offset) <<
"entry " << i;
157 running += entries[i].Ptlm;
189 j2c_file.
open(filename);
197 cur_line->i32[x] = (
ojph::si32)((x + y) & 0xFF);
198 cur_line = codestream.
exchange(cur_line, next_comp);
205 void decode(
const char* filename)
209 j2c_file.
open(filename);
216 codestream.
pull(comp_num);
223TEST(TestTLM, SingleSegmentBelowLimit) {
224 const char* filename =
"tlm_single_segment.j2c";
226 encode(filename, 512, 512, 32, 1);
228 std::vector<tlm_seg> segs;
229 std::vector<tlm_entry> entries;
230 std::vector<tile_part> parts;
231 size_t header_end = 0;
232 ASSERT_NO_FATAL_FAILURE(scan(filename, segs, entries, parts, header_end));
234 EXPECT_EQ(parts.size(), 512u);
235 ASSERT_EQ(segs.size(), 1u);
236 EXPECT_EQ(segs[0].Ztlm, 0);
237 EXPECT_EQ(segs[0].count, (
ojph::ui32)parts.size());
238 ASSERT_NO_FATAL_FAILURE(
239 expect_entries_describe_tileparts(entries, parts, header_end));
249TEST(TestTLM, MultipleSegmentsAboveLimit) {
250 const char* filename =
"tlm_multiple_segments.j2c";
253 encode(filename, 512, 512, 8, 2);
255 std::vector<tlm_seg> segs;
256 std::vector<tlm_entry> entries;
257 std::vector<tile_part> parts;
258 size_t header_end = 0;
259 ASSERT_NO_FATAL_FAILURE(scan(filename, segs, entries, parts, header_end));
261 EXPECT_EQ(parts.size(), 12288u);
262 ASSERT_EQ(segs.size(), 2u);
265 for (
size_t i = 0; i < segs.size(); ++i)
268 EXPECT_EQ(segs[i].Stlm, 0x60);
269 if (i + 1 < segs.size())
270 EXPECT_EQ(segs[i].count, MAX_PAIRS_PER_SEG);
271 total += segs[i].count;
274 ASSERT_NO_FATAL_FAILURE(
275 expect_entries_describe_tileparts(entries, parts, header_end));
285TEST(TestTLM, ExactlyOneFullSegment) {
286 const char* filename =
"tlm_exactly_full.j2c";
288 encode(filename, 536, 1304, 8, 0);
290 std::vector<tlm_seg> segs;
291 std::vector<tlm_entry> entries;
292 std::vector<tile_part> parts;
293 size_t header_end = 0;
294 ASSERT_NO_FATAL_FAILURE(scan(filename, segs, entries, parts, header_end));
296 EXPECT_EQ(parts.size(), MAX_PAIRS_PER_SEG);
297 ASSERT_EQ(segs.size(), 1u);
298 EXPECT_EQ(segs[0].Ztlm, 0);
299 EXPECT_EQ(segs[0].count, MAX_PAIRS_PER_SEG);
300 ASSERT_NO_FATAL_FAILURE(
301 expect_entries_describe_tileparts(entries, parts, header_end));
310TEST(TestTLM, OneEntryPastFullSegment) {
311 const char* filename =
"tlm_one_past_full.j2c";
313 encode(filename, 688, 1016, 8, 0);
315 std::vector<tlm_seg> segs;
316 std::vector<tlm_entry> entries;
317 std::vector<tile_part> parts;
318 size_t header_end = 0;
319 ASSERT_NO_FATAL_FAILURE(scan(filename, segs, entries, parts, header_end));
321 EXPECT_EQ(parts.size(), MAX_PAIRS_PER_SEG + 1);
322 ASSERT_EQ(segs.size(), 2u);
323 EXPECT_EQ(segs[0].Ztlm, 0);
324 EXPECT_EQ(segs[0].count, MAX_PAIRS_PER_SEG);
325 EXPECT_EQ(segs[1].Ztlm, 1);
326 EXPECT_EQ(segs[1].count, 1u);
327 ASSERT_NO_FATAL_FAILURE(
328 expect_entries_describe_tileparts(entries, parts, header_end));
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 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...
void request_tlm_marker(bool needed)
Request the addition of the optional TLM marker segment. This request should occur before writing cod...
void read_headers(infile_base *file)
This call reads the headers of a codestream. It is for a reading (or decoding) codestream,...
void set_tilepart_divisions(bool at_resolutions, bool at_components)
Sets the locations where a tile is partitioned into tile parts.
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_...
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)
void set_num_decomposition(ui32 num_decompositions)
void set_progression_order(const char *name)
void set_block_dims(ui32 width, ui32 height)
void set_color_transform(bool color_transform)
void set_reversible(bool reversible)
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)
void set_tile_offset(point offset)
void set_image_offset(point offset)
void set_image_extent(point extent)
TEST(TestExecutables, OpenJPHCompressNoArguments)