OpenJPH Open-source implementation of JPEG2000 Part-15

Loading...
Searching...
No Matches
test_mixed_coc.cpp
Go to the documentation of this file.
1//***************************************************************************/
2// This software is released under the 2-Clause BSD license, included
3// below.
4//
5// Copyright (c) Pierre-Anthony Lemieux
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11// 1. Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13//
14// 2. Redistributions in binary form must reproduce the above copyright
15// notice, this list of conditions and the following disclaimer in the
16// documentation and/or other materials provided with the distribution.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
19// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//***************************************************************************/
30// This file is part of the OpenJPH software implementation.
31// File: test_mixed_coc.cpp
32// Author: Pierre-Anthony Lemieux
33// Date: 29 June 2026
34//***************************************************************************/
35
36#include <cstring>
37#include <vector>
38
39#include "ojph_mem.h"
40#include "ojph_file.h"
41#include "ojph_codestream.h"
42#include "ojph_params.h"
43#include "gtest/gtest.h"
44
46// Test encoding a 4-component image where 3 components use the irreversible
47// (9/7) wavelet and 1 component uses the reversible (5/3) wavelet.
48// This exercises COC and QCC marker generation for mixed coding modes.
49// Verifies that encoding succeeds, headers can be read back, and the
50// per-component coding settings are preserved.
51 TEST(TestMixedCOC, FourCompMixedReversibility) {
52 const ojph::ui32 width = 64;
53 const ojph::ui32 height = 64;
54 const ojph::ui32 num_comps = 4;
55 const ojph::ui32 bit_depth = 8;
56 const ojph::ui32 num_decomps = 5;
57
58 // samples fed into component 3 during encoding, kept around so they can
59 // be compared against the decoded output further down
60 std::vector<ojph::si32> comp3_orig(width * height);
61
62 // encode
63 {
64 ojph::codestream codestream;
65
66 ojph::param_siz siz = codestream.access_siz();
67 siz.set_image_extent(ojph::point(width, height));
68 siz.set_num_components(num_comps);
69 for (ojph::ui32 c = 0; c < num_comps; ++c)
70 siz.set_component(c, ojph::point(1, 1), bit_depth, false);
71 siz.set_image_offset(ojph::point(0, 0));
72 siz.set_tile_size(ojph::size(width, height));
73 siz.set_tile_offset(ojph::point(0, 0));
74
75 ojph::param_cod cod = codestream.access_cod();
76 cod.set_num_decomposition(num_decomps);
77 cod.set_block_dims(64, 64);
78 cod.set_color_transform(false);
79 cod.set_reversible(false);
80
81 cod.set_reversible(3, true);
82
83 codestream.access_qcd().set_irrev_quant(0.01f);
84 codestream.set_planar(true);
85
86 ojph::j2c_outfile j2c_file;
87 j2c_file.open("mixed_rev_irrev_4comp.j2c");
88 codestream.write_headers(&j2c_file);
89
90 ojph::ui32 next_comp;
91 ojph::line_buf* cur_line = codestream.exchange(NULL, next_comp);
92
93 for (ojph::ui32 c = 0; c < num_comps; ++c)
94 {
95 for (ojph::ui32 y = 0; y < height; ++y)
96 {
97 ASSERT_EQ(next_comp, c);
98 if (c == 3)
99 {
100 // non-constant pattern so a roundtrip mismatch would be caught
101 for (ojph::ui32 x = 0; x < width; ++x)
102 {
103 ojph::si32 val = (ojph::si32)((x + y * width) % 256);
104 cur_line->i32[x] = val;
105 comp3_orig[y * width + x] = val;
106 }
107 }
108 else if (cur_line->flags & ojph::line_buf::LFT_INTEGER)
109 memset(cur_line->i32, 0,
110 sizeof(ojph::si32) * cur_line->size);
111 else
112 memset(cur_line->f32, 0,
113 sizeof(float) * cur_line->size);
114 cur_line = codestream.exchange(cur_line, next_comp);
115 }
116 }
117
118 codestream.flush();
119 codestream.close();
120 }
121
122 // read back headers and verify per-component settings
123 {
124 ojph::codestream codestream;
125 ojph::j2c_infile j2c_file;
126 j2c_file.open("mixed_rev_irrev_4comp.j2c");
127 codestream.read_headers(&j2c_file);
128
129 ojph::param_siz siz = codestream.access_siz();
130 EXPECT_EQ(siz.get_num_components(), num_comps);
131 for (ojph::ui32 c = 0; c < num_comps; ++c)
132 EXPECT_EQ(siz.get_bit_depth(c), bit_depth);
133
134 ojph::param_cod cod = codestream.access_cod();
135 EXPECT_FALSE(cod.is_reversible());
136
137 for (ojph::ui32 c = 0; c < 3; ++c) {
138 EXPECT_FALSE(cod.is_reversible(c))
139 << "Component " << c << " should be irreversible";
140 }
141
142 EXPECT_TRUE(cod.is_reversible(3))
143 << "Component 3 should be reversible";
144
145 // decode all components and verify component 3 (reversible) samples
146 // are identical to what was encoded
147 codestream.restrict_input_resolution(0, 0);
148 codestream.set_planar(true);
149 codestream.create();
150
151 for (ojph::ui32 c = 0; c < num_comps; ++c)
152 {
153 ojph::ui32 comp_height = siz.get_recon_height(c);
154 ojph::ui32 comp_width = siz.get_recon_width(c);
155 for (ojph::ui32 y = 0; y < comp_height; ++y)
156 {
157 ojph::ui32 comp_num;
158 ojph::line_buf* line = codestream.pull(comp_num);
159 ASSERT_EQ(comp_num, c);
160 if (c == 3)
161 {
162 ASSERT_EQ(comp_width, width);
163 for (ojph::ui32 x = 0; x < width; ++x)
164 EXPECT_EQ(line->i32[x], comp3_orig[y * width + x])
165 << "Component 3 sample mismatch at (" << x << ", " << y << ")";
166 }
167 }
168 }
169
170 codestream.close();
171 }
172}
173
175 int main(int argc, char** argv) {
176 ::testing::InitGoogleTest(&argc, argv);
177 return RUN_ALL_TESTS();
178}
ojph::codestream
The object represent a codestream.
Definition ojph_codestream.h:89
ojph::codestream::access_siz
param_siz access_siz()
Returns the underlying SIZ marker segment object.
Definition ojph_codestream.cpp:79
ojph::codestream::access_cod
param_cod access_cod()
Returns the underlying COD marker segment object.
Definition ojph_codestream.cpp:85
ojph::codestream::restrict_input_resolution
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...
Definition ojph_codestream.cpp:179
ojph::codestream::close
void close()
Call this function to close the underlying file; works for both encoding and decoding codestreams.
Definition ojph_codestream.cpp:206
ojph::codestream::set_planar
void set_planar(bool planar)
Sets the sequence of pushing or pull rows from the machinery.
Definition ojph_codestream.cpp:103
ojph::codestream::exchange
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...
Definition ojph_codestream.cpp:212
ojph::codestream::access_qcd
param_qcd access_qcd()
Returns the underlying QCD marker segment object.
Definition ojph_codestream.cpp:91
ojph::codestream::read_headers
void read_headers(infile_base *file)
This call reads the headers of a codestream. It is for a reading (or decoding) codestream,...
Definition ojph_codestream.cpp:173
ojph::codestream::write_headers
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...
Definition ojph_codestream.cpp:159
ojph::codestream::create
void create()
This call is for a decoding (or reading) codestream. Call this function after calling restrict_input_...
Definition ojph_codestream.cpp:187
ojph::codestream::flush
void flush()
This is the last call to a writing (encoding) codestream. This will write encoded bitstream data to t...
Definition ojph_codestream.cpp:200
ojph::codestream::pull
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...
Definition ojph_codestream.cpp:193
ojph::j2c_infile
Definition ojph_file.h:288
ojph::j2c_infile::open
void open(const char *filename)
Definition ojph_file.cpp:274
ojph::j2c_outfile
Definition ojph_file.h:98
ojph::j2c_outfile::open
void open(const char *filename)
Definition ojph_file.cpp:62
ojph::line_buf
Definition ojph_mem.h:161
ojph::line_buf::LFT_INTEGER
@ LFT_INTEGER
Definition ojph_mem.h:170
ojph::line_buf::size
size_t size
Definition ojph_mem.h:181
ojph::line_buf::flags
ui32 flags
Definition ojph_mem.h:183
ojph::line_buf::f32
float * f32
Definition ojph_mem.h:187
ojph::line_buf::i32
si32 * i32
Definition ojph_mem.h:185
ojph::param_cod
Definition ojph_params.h:120
ojph::param_cod::set_num_decomposition
void set_num_decomposition(ui32 num_decompositions)
Definition ojph_params.cpp:165
ojph::param_cod::is_reversible
bool is_reversible() const
Definition ojph_params.cpp:302
ojph::param_cod::set_block_dims
void set_block_dims(ui32 width, ui32 height)
Definition ojph_params.cpp:174
ojph::param_cod::set_color_transform
void set_color_transform(bool color_transform)
Definition ojph_params.cpp:243
ojph::param_cod::set_reversible
void set_reversible(bool reversible)
Definition ojph_params.cpp:249
ojph::param_qcd::set_irrev_quant
void set_irrev_quant(float delta)
Set the irreversible quantization base delta.
Definition ojph_params.cpp:411
ojph::param_siz
Definition ojph_params.h:69
ojph::param_siz::set_tile_size
void set_tile_size(size s)
Definition ojph_params.cpp:66
ojph::param_siz::set_component
void set_component(ui32 comp_num, const point &downsampling, ui32 bit_depth, bool is_signed)
Definition ojph_params.cpp:90
ojph::param_siz::set_num_components
void set_num_components(ui32 num_comps)
Definition ojph_params.cpp:84
ojph::param_siz::get_bit_depth
ui32 get_bit_depth(ui32 comp_num) const
Definition ojph_params.cpp:127
ojph::param_siz::set_tile_offset
void set_tile_offset(point offset)
Definition ojph_params.cpp:78
ojph::param_siz::set_image_offset
void set_image_offset(point offset)
Definition ojph_params.cpp:72
ojph::param_siz::get_recon_height
ui32 get_recon_height(ui32 comp_num) const
Definition ojph_params.cpp:151
ojph::param_siz::set_image_extent
void set_image_extent(point extent)
Definition ojph_params.cpp:60
ojph::param_siz::get_recon_width
ui32 get_recon_width(ui32 comp_num) const
Definition ojph_params.cpp:145
ojph::param_siz::get_num_components
ui32 get_num_components() const
Definition ojph_params.cpp:121
ojph::si32
int32_t si32
Definition ojph_defs.h:55
ojph::ui32
uint32_t ui32
Definition ojph_defs.h:54
ojph_codestream.h
ojph_file.h
ojph_mem.h
ojph_params.h
ojph::point
Definition ojph_base.h:58
ojph::size
Definition ojph_base.h:48
main
int main(int argc, char **argv)
Definition test_mixed_coc.cpp:175
TEST
TEST(TestMixedCOC, FourCompMixedReversibility)
Definition test_mixed_coc.cpp:51