comparison Framework/Inputs/HierarchicalTiff.cpp @ 218:c5a8b46c4cba

Fix colorspace of TIFF containing JPEG with RGB photometric interpretation
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 12 Jan 2021 16:20:57 +0100
parents 1e864138f0da
children 49f647ed1b4c
comparison
equal deleted inserted replaced
217:20bc074ec19a 218:c5a8b46c4cba
325 static_cast<uint8_t>(raw[1]) != 0xd8) 325 static_cast<uint8_t>(raw[1]) != 0xd8)
326 { 326 {
327 throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); 327 throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile);
328 } 328 }
329 329
330 tile.resize(headers.size() + raw.size() - 2); 330 if (photometric_ == Orthanc::PhotometricInterpretation_RGB &&
331 memcpy(&tile[0], &headers[0], headers.size()); 331 pixelFormat_ == Orthanc::PixelFormat_RGB24)
332 memcpy(&tile[0] + headers.size(), &raw[2], raw.size() - 2); 332 {
333 } 333 /**
334 334 * Insert an Adobe APP14 marker with the "transform" flag set
335 * to value 0, which indicates to the JPEG decoder that
336 * "3-channel images are assumed to be RGB". Section 18 of
337 * "Supporting the DCT Filters in PostScript Level 2 -
338 * Technical Note #5116":
339 * https://stackoverflow.com/a/9658206/881731
340 * https://docs.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html
341 * https://www.pdfa.org/wp-content/uploads/2020/07/5116.DCT_Filter.pdf
342 **/
343 static const uint8_t APP14[] = {
344 0xff, 0xee, /* JPEG Marker for Adobe segment: http://www.ozhiker.com/electronics/pjmt/jpeg_info/app_segments.html */
345 0x00, 0x0e, /* Length (without the JPEG marker) == 0x0e == 14 bytes */
346 0x41, 0x64, 0x6f, 0x62, 0x65, /* "Adobe" string in ASCII */
347 0x00, 0x64, /* Version == Two-byte DCTEncode/DCTDecode version number == 0x64 */
348 0x80, 0x00, /* Two-byte "flags0" 0x8000 bit: Encoder used Blend=1 downsampling */
349 0x00, 0x00, /* Two-byte "flags1": Set to zero */
350 0x00 /* One-byte color transform code == 0 <== This is the important one */
351 };
352 assert(sizeof(APP14) == 16);
353
354 tile.resize(headers.size() + sizeof(APP14) + raw.size() - 2);
355 memcpy(&tile[0], &headers[0], headers.size());
356 memcpy(&tile[0] + headers.size(), APP14, sizeof(APP14));
357 memcpy(&tile[0] + headers.size() + sizeof(APP14), &raw[2], raw.size() - 2);
358 }
359 else
360 {
361 tile.resize(headers.size() + raw.size() - 2);
362 memcpy(&tile[0], &headers[0], headers.size());
363 memcpy(&tile[0] + headers.size(), &raw[2], raw.size() - 2);
364 }
365 }
366
335 return true; 367 return true;
336 } 368 }
337 } 369 }