Skip to content

Commit aa7a38c

Browse files
committed
add 32-bit float TIF output support to ojph_expand
1 parent 7657919 commit aa7a38c

File tree

3 files changed

+95
-22
lines changed

3 files changed

+95
-22
lines changed

src/apps/common/ojph_img_io.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,11 @@ namespace ojph {
650650
buffer = NULL;
651651
width = height = num_components = 0;
652652
bytes_per_sample = 0;
653-
bit_depth_of_data[0] = bit_depth_of_data[1] = 0;
654-
bit_depth_of_data[2] = bit_depth_of_data[3] = 0;
653+
for (int c = 0; c < 3; c++)
654+
{
655+
bit_depth_of_data[c] = 0;
656+
is_signed[c] = false;
657+
}
655658
buffer_size = 0;
656659
cur_line = samples_per_line = 0;
657660
bytes_per_line = 0;
@@ -667,7 +670,7 @@ namespace ojph {
667670

668671
void open(char* filename);
669672
void configure(ui32 width, ui32 height, ui32 num_components,
670-
ui32 *bit_depth);
673+
ui32 *bit_depth, bool* is_signed, bool* has_nlt_type3);
671674
virtual ui32 write(const line_buf* line, ui32 comp_num);
672675
virtual void close() {
673676
if (tiff_handle) {
@@ -685,6 +688,8 @@ namespace ojph {
685688
const char* fname;
686689
ui32 width, height, num_components;
687690
ui32 bit_depth_of_data[4];
691+
bool is_signed[4];
692+
bool has_nlt_type3[4];
688693
ui32 bytes_per_sample;
689694
ui8* buffer;
690695
size_t buffer_size;

src/apps/ojph_expand/ojph_expand.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ int main(int argc, char *argv[]) {
325325
{
326326
codestream.set_planar(false);
327327
ojph::param_siz siz = codestream.access_siz();
328+
ojph::param_nlt nlt = codestream.access_nlt();
328329

329330
bool all_same = true;
330331
ojph::point p = siz.get_downsampling(0);
@@ -338,12 +339,29 @@ int main(int argc, char *argv[]) {
338339
"To save an image to tif(f), all the components must have the "
339340
"same downsampling ratio\n");
340341
ojph::ui32 bit_depths[4] = { 0, 0, 0, 0 };
341-
for (ojph::ui32 c = 0; c < siz.get_num_components(); c++)
342+
bool is_signeds[4] = { false, false, false, false };
343+
bool has_nlt_type3[4] = { false, false, false, false };
344+
for (ojph::ui32 c = 0; c < (siz.get_num_components() > 4 ? 4 : siz.get_num_components()); c++)
342345
{
343346
bit_depths[c] = siz.get_bit_depth(c);
347+
is_signeds[c] = siz.is_signed(c);
348+
bool nlt_is_signed;
349+
ojph::ui8 nlt_bit_depth;
350+
has_nlt_type3[c] = nlt.get_type3_transformation(c, nlt_bit_depth, nlt_is_signed);
351+
352+
if (true == has_nlt_type3[c] && (nlt_bit_depth != siz.get_bit_depth(c) || nlt_is_signed != siz.is_signed(c)))
353+
{
354+
OJPH_ERROR(0x02000005,
355+
"There is discrepancy in component %d configuration between "
356+
"SIZ marker segment, which specifies bit_depth = %d and "
357+
"signedness = %s, and NLT marker segment, which specifies "
358+
"bit_depth = %d and signedness = %s.\n", c,
359+
siz.get_bit_depth(c), siz.is_signed(c) ? "True" : "False",
360+
nlt_bit_depth, nlt_is_signed ? "True" : "False");
361+
}
344362
}
345363
tif.configure(siz.get_recon_width(0), siz.get_recon_height(0),
346-
siz.get_num_components(), bit_depths);
364+
siz.get_num_components(), bit_depths, is_signeds, has_nlt_type3);
347365
tif.open(output_filename);
348366
base = &tif;
349367
}

src/apps/others/ojph_img_io.cpp

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,12 +1091,17 @@ namespace ojph {
10911091
{
10921092
// Error on known incompatilbe output formats
10931093
ui32 max_bitdepth = 0;
1094+
bool any_component_has_nlt_type3 = false;
10941095
for (ui32 c = 0; c < num_components; c++)
10951096
{
10961097
if (bit_depth_of_data[c] > max_bitdepth)
10971098
max_bitdepth = bit_depth_of_data[c];
1099+
1100+
if (has_nlt_type3[c] == true)
1101+
any_component_has_nlt_type3 = true;
10981102
}
1099-
if (max_bitdepth > 16)
1103+
1104+
if (max_bitdepth > 16 && max_bitdepth != 32 && any_component_has_nlt_type3 == false )
11001105
{
11011106
OJPH_WARN(0x030000B1, "TIFF output is currently limited to files "
11021107
"with max_bitdepth = 16, the source codestream has max_bitdepth=%d"
@@ -1116,6 +1121,10 @@ namespace ojph {
11161121

11171122
buffer_size = width * (size_t)num_components * (size_t)bytes_per_sample;
11181123
buffer = (ui8*)malloc(buffer_size);
1124+
if(NULL == buffer)
1125+
{
1126+
OJPH_ERROR(0x030000B4, "unable to allocate %ul bytes for buffer[]", buffer_size);
1127+
}
11191128
fname = filename;
11201129
cur_line = 0;
11211130

@@ -1160,38 +1169,49 @@ namespace ojph {
11601169

11611170
TIFFSetField(tiff_handle, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
11621171
TIFFSetField(tiff_handle, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1163-
//TIFFSetField(tiff_handle, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
1172+
if (32 == max_bitdepth)
1173+
{
1174+
TIFFSetField(tiff_handle, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
1175+
}
11641176
TIFFSetField(tiff_handle, TIFFTAG_ROWSPERSTRIP, height);
11651177

11661178
}
11671179

11681180
////////////////////////////////////////////////////////////////////////////
11691181
void tif_out::configure(ui32 width, ui32 height, ui32 num_components,
1170-
ui32 *bit_depth)
1182+
ui32 *bit_depth, bool *is_signed, bool *has_nlt_type3)
11711183
{
11721184
assert(tiff_handle == NULL); //configure before opening
11731185

11741186
this->width = width;
11751187
this->height = height;
11761188
this->num_components = num_components;
11771189
ui32 max_bitdepth = 0;
1190+
bool any_component_has_nlt_type3 = false;
11781191
for (ui32 c = 0; c < num_components; c++)
11791192
{
11801193
this->bit_depth_of_data[c] = bit_depth[c];
11811194
if (bit_depth[c] > max_bitdepth)
11821195
max_bitdepth = bit_depth[c];
1196+
1197+
this->is_signed[c] = is_signed[c];
1198+
this->has_nlt_type3[c] = has_nlt_type3[c];
1199+
if (has_nlt_type3[c] == true)
1200+
any_component_has_nlt_type3 = true;
11831201
}
11841202

1185-
bytes_per_sample = (max_bitdepth + 7) / 8; // round up
1186-
if (bytes_per_sample > 2)
1187-
{
1188-
// TIFF output is currently limited to files with max_bitdepth = 16,
1189-
// the decoded data will be truncated to 16 bits
1203+
if (max_bitdepth <= 8)
1204+
bytes_per_sample = 1;
1205+
else if (max_bitdepth <= 16)
11901206
bytes_per_sample = 2;
1191-
}
1207+
else
1208+
bytes_per_sample = 4;
1209+
1210+
if(any_component_has_nlt_type3)
1211+
bytes_per_sample = 4;
1212+
11921213
samples_per_line = num_components * width;
11931214
bytes_per_line = bytes_per_sample * (size_t)samples_per_line;
1194-
11951215
}
11961216

11971217
////////////////////////////////////////////////////////////////////////////
@@ -1295,16 +1315,46 @@ namespace ojph {
12951315
// 16 bit MSB
12961316
*dp = (ui16)((val >> bits_to_shift) & bit_mask);
12971317
}
1298-
}
1299-
1318+
}
13001319
}
1301-
// write scanline when the last component is reached
1302-
if (comp_num == num_components-1)
1320+
else if (bytes_per_sample == 4)
1321+
{
1322+
1323+
// float32 was compressed
1324+
if (has_nlt_type3[comp_num] == true)
13031325
{
1304-
int result = TIFFWriteScanline(tiff_handle, buffer, cur_line++);
1305-
if (result != 1)
1306-
OJPH_ERROR(0x030000C1, "error writing to file %s", fname);
1326+
if (bit_depth_of_data[comp_num] == 32)
1327+
{
1328+
const float* sp = line->f32;
1329+
float* dp = (float*)buffer + comp_num;
1330+
for (ui32 i = width; i > 0; --i, dp += num_components)
1331+
{
1332+
float val = *sp++;
1333+
*dp = val;
1334+
}
1335+
}
1336+
else
1337+
{
1338+
OJPH_ERROR(0x030000C1,
1339+
"bytes_per_sample = 4 has_nlt_type3[%d] = true and bit_depth_of_data[%d]=%d is not yet supported",
1340+
comp_num, comp_num, bit_depth_of_data[comp_num]);
1341+
}
13071342
}
1343+
else
1344+
{
1345+
OJPH_ERROR(0x030000C2,
1346+
"bytes_per_sample = 4 has_nlt_type3[%d] = false is not yet supported",
1347+
comp_num);
1348+
}
1349+
}
1350+
1351+
// write scanline when the last component is reached
1352+
if (comp_num == num_components-1)
1353+
{
1354+
int result = TIFFWriteScanline(tiff_handle, buffer, cur_line++);
1355+
if (result != 1)
1356+
OJPH_ERROR(0x030000C3, "error writing to file %s", fname);
1357+
}
13081358
return 0;
13091359
}
13101360
#endif /* OJPH_ENABLE_TIFF_SUPPORT */

0 commit comments

Comments
 (0)