16e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 26e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// Copyright 2011 Adobe Systems Incorporated 36e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// All Rights Reserved. 46e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// 56e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// NOTICE: Adobe permits you to use, modify, and distribute this file in 66e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim// accordance with the terms of the Adobe license agreement accompanying it. 76e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 86e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 96e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_jpeg_image.cpp#1 $ */ 106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $DateTime: 2012/05/30 13:28:51 $ */ 116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Change: 832332 $ */ 126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/* $Author: tknoll $ */ 136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_jpeg_image.h" 176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_abort_sniffer.h" 196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_area_task.h" 206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_assertions.h" 216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_host.h" 226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_ifd.h" 236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_image.h" 246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_image_writer.h" 256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_memory_stream.h" 266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_mutex.h" 276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim#include "dng_safe_arithmetic.h" 286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_jpeg_image::dng_jpeg_image () 326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim : fImageSize () 346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fTileSize () 356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fUsesStrips (false) 366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fJPEGTables () 376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fJPEGData () 386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimclass dng_jpeg_image_encode_task : public dng_area_task 466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim private: 496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_host &fHost; 516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_image_writer &fWriter; 536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_image &fImage; 556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image &fJPEGImage; 576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 fTileCount; 596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_ifd &fIFD; 616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_mutex fMutex; 636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 fNextTileIndex; 656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim public: 676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_encode_task (dng_host &host, 696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_image_writer &writer, 706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_image &image, 716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image &jpegImage, 726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tileCount, 736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_ifd &ifd) 746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim : fHost (host) 766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fWriter (writer) 776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fImage (image) 786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fJPEGImage (jpegImage) 796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fTileCount (tileCount) 806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fIFD (ifd) 816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fMutex ("dng_jpeg_image_encode_task") 826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fNextTileIndex (0) 836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fMinTaskArea = 16 * 16; 876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fUnitCell = dng_point (16, 16); 886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fMaxTileSize = dng_point (16, 16); 896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim void Process (uint32 /* threadIndex */, 936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_rect & /* tile */, 946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_abort_sniffer *sniffer) 956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim AutoPtr<dng_memory_block> compressedBuffer; 986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim AutoPtr<dng_memory_block> uncompressedBuffer; 996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim AutoPtr<dng_memory_block> subTileBlockBuffer; 1006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim AutoPtr<dng_memory_block> tempBuffer; 1016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 uncompressedSize = SafeUint32Mult ( 1036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fIFD.fTileLength, fIFD.fTileWidth, fIFD.fSamplesPerPixel); 1046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uncompressedBuffer.Reset (fHost.Allocate (uncompressedSize)); 1066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tilesAcross = fIFD.TilesAcross (); 1086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim while (true) 1106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 1116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tileIndex; 1136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 1156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_lock_mutex lock (&fMutex); 1176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim if (fNextTileIndex == fTileCount) 1196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 1206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim return; 1216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 1226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim tileIndex = fNextTileIndex++; 1246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 1266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_abort_sniffer::SniffForAbort (sniffer); 1286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 rowIndex = tileIndex / tilesAcross; 1306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 colIndex = tileIndex % tilesAcross; 1316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_rect tileArea = fIFD.TileArea (rowIndex, colIndex); 1336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_memory_stream stream (fHost.Allocator ()); 1356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fWriter.WriteTile (fHost, 1376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fIFD, 1386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim stream, 1396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fImage, 1406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim tileArea, 1416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1, 1426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim compressedBuffer, 1436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uncompressedBuffer, 1446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim subTileBlockBuffer, 1456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim tempBuffer); 1466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fJPEGImage.fJPEGData [tileIndex].Reset (stream.AsMemoryBlock (fHost.Allocator ())); 1486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 1506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 1526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim private: 1546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // Hidden copy constructor and assignment operator. 1566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_encode_task (const dng_jpeg_image_encode_task &); 1586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_encode_task & operator= (const dng_jpeg_image_encode_task &); 1606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim }; 1626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 1646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimvoid dng_jpeg_image::Encode (dng_host &host, 1666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_negative &negative, 1676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_image_writer &writer, 1686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_image &image) 1696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 1706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim #if qDNGValidate 1726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_timer timer ("Encode JPEG Proxy time"); 1736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim #endif 1746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim DNG_ASSERT (image.PixelType () == ttByte, "Cannot JPEG encode non-byte image"); 1766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fImageSize = image.Bounds ().Size (); 1786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_ifd ifd; 1806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fImageWidth = fImageSize.h; 1826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fImageLength = fImageSize.v; 1836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fSamplesPerPixel = image.Planes (); 1856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fBitsPerSample [0] = 8; 1876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fBitsPerSample [1] = 8; 1886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fBitsPerSample [2] = 8; 1896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fBitsPerSample [3] = 8; 1906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fPhotometricInterpretation = piLinearRaw; 1926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fCompression = ccLossyJPEG; 1946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.FindTileSize (512 * 512 * ifd.fSamplesPerPixel); 1966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 1976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fTileSize.h = ifd.fTileWidth; 1986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fTileSize.v = ifd.fTileLength; 1996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // Need a higher quality for raw proxies than non-raw proxies, 2016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // since users often perform much greater color changes. Also, use 2026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // we are targeting a "large" size proxy (larger than 5MP pixels), or this 2036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // is a full size proxy, then use a higher quality. 2046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim bool useHigherQuality = (uint64) ifd.fImageWidth * 2066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim (uint64) ifd.fImageLength > 5000000 || 2076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim image.Bounds ().Size () == negative.OriginalDefaultFinalSize (); 2086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim if (negative.ColorimetricReference () == crSceneReferred) 2106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fCompressionQuality = useHigherQuality ? 11 : 10; 2126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 2136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim else 2146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd.fCompressionQuality = useHigherQuality ? 10 : 8; 2166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 2176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tilesAcross = ifd.TilesAcross (); 2196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tilesDown = ifd.TilesDown (); 2206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tileCount = tilesAcross * tilesDown; 2226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fJPEGData.Reset (tileCount); 2246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 threadCount = Min_uint32 (tileCount, 2266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim host.PerformAreaTaskThreads ()); 2276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_encode_task task (host, 2296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim writer, 2306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim image, 2316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim *this, 2326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim tileCount, 2336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim ifd); 2346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim host.PerformAreaTask (task, 2366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_rect (0, 0, 16, 16 * threadCount)); 2376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 2396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 2416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimclass dng_jpeg_image_find_digest_task : public dng_area_task 2436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim private: 2466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_jpeg_image &fJPEGImage; 2486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 fTileCount; 2506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_fingerprint *fDigests; 2526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_mutex fMutex; 2546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 fNextTileIndex; 2566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim public: 2586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_find_digest_task (const dng_jpeg_image &jpegImage, 2606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tileCount, 2616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_fingerprint *digests) 2626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim : fJPEGImage (jpegImage) 2646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fTileCount (tileCount) 2656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fDigests (digests) 2666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fMutex ("dng_jpeg_image_find_digest_task") 2676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim , fNextTileIndex (0) 2686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fMinTaskArea = 16 * 16; 2726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fUnitCell = dng_point (16, 16); 2736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fMaxTileSize = dng_point (16, 16); 2746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 2766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim void Process (uint32 /* threadIndex */, 2786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim const dng_rect & /* tile */, 2796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_abort_sniffer *sniffer) 2806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim while (true) 2836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tileIndex; 2866e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2876e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2886e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2896e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_lock_mutex lock (&fMutex); 2906e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2916e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim if (fNextTileIndex == fTileCount) 2926e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 2936e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim return; 2946e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 2956e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2966e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim tileIndex = fNextTileIndex++; 2976e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 2986e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 2996e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3006e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_abort_sniffer::SniffForAbort (sniffer); 3016e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3026e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_md5_printer printer; 3036e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3046e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim printer.Process (fJPEGImage.fJPEGData [tileIndex]->Buffer (), 3056e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fJPEGImage.fJPEGData [tileIndex]->LogicalSize ()); 3066e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3076e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fDigests [tileIndex] = printer.Result (); 3086e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3096e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3106e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3116e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3126e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3136e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim private: 3146e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3156e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // Hidden copy constructor and assignment operator. 3166e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3176e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_find_digest_task (const dng_jpeg_image_find_digest_task &); 3186e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3196e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_find_digest_task & operator= (const dng_jpeg_image_find_digest_task &); 3206e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3216e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim }; 3226e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3236e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 3246e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3256e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakimdng_fingerprint dng_jpeg_image::FindDigest (dng_host &host) const 3266e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 3276e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3286e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 tileCount = TileCount (); 3296e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3306e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 arrayCount = tileCount + (fJPEGTables.Get () ? 1 : 0); 3316e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3326e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim AutoArray<dng_fingerprint> digests (arrayCount); 3336e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3346e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // Compute digest of each compressed tile. 3356e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3366e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 3376e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3386e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim uint32 threadCount = Min_uint32 (tileCount, 3396e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim host.PerformAreaTaskThreads ()); 3406e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3416e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_jpeg_image_find_digest_task task (*this, 3426e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim tileCount, 3436e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim digests.Get ()); 3446e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3456e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim host.PerformAreaTask (task, 3466e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_rect (0, 0, 16, 16 * threadCount)); 3476e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3486e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3496e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3506e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // Compute digest of JPEG tables, if any. 3516e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3526e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim if (fJPEGTables.Get ()) 3536e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 3546e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3556e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_md5_printer printer; 3566e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3576e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim printer.Process (fJPEGTables->Buffer (), 3586e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim fJPEGTables->LogicalSize ()); 3596e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3606e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim digests [tileCount] = printer.Result (); 3616e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3626e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3636e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3646e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim // Combine digests into a single digest. 3656e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3666e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 3676e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3686e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_md5_printer printer; 3696e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3706e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim for (uint32 k = 0; k < arrayCount; k++) 3716e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim { 3726e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3736e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim printer.Process (digests [k].data, 3746e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim dng_fingerprint::kDNGFingerprintSize); 3756e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3766e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3776e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3786e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim return printer.Result (); 3796e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3806e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3816e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3826e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim } 3836e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 3846e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim/*****************************************************************************/ 3856e09dfbee0b1643a5cb2b32d0399c1a0c69551a0Kinan Hakim 386