2
0

tif_overview.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. /******************************************************************************
  2. * tif_overview.c,v 1.9 2005/05/25 09:03:16 dron Exp
  3. *
  4. * Project: TIFF Overview Builder
  5. * Purpose: Library function for building overviews in a TIFF file.
  6. * Author: Frank Warmerdam, warmerdam@pobox.com
  7. *
  8. * Notes:
  9. * o Currently only images with bits_per_sample of a multiple of eight
  10. * will work.
  11. *
  12. * o The downsampler currently just takes the top left pixel from the
  13. * source rectangle. Eventually sampling options of averaging, mode, and
  14. * ``center pixel'' should be offered.
  15. *
  16. * o The code will attempt to use the same kind of compression,
  17. * photometric interpretation, and organization as the source image, but
  18. * it doesn't copy geotiff tags to the reduced resolution images.
  19. *
  20. * o Reduced resolution overviews for multi-sample files will currently
  21. * always be generated as PLANARCONFIG_SEPARATE. This could be fixed
  22. * reasonable easily if needed to improve compatibility with other
  23. * packages. Many don't properly support PLANARCONFIG_SEPARATE.
  24. *
  25. ******************************************************************************
  26. * Copyright (c) 1999, Frank Warmerdam
  27. *
  28. * Permission is hereby granted, free of charge, to any person obtaining a
  29. * copy of this software and associated documentation files (the "Software"),
  30. * to deal in the Software without restriction, including without limitation
  31. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  32. * and/or sell copies of the Software, and to permit persons to whom the
  33. * Software is furnished to do so, subject to the following conditions:
  34. *
  35. * The above copyright notice and this permission notice shall be included
  36. * in all copies or substantial portions of the Software.
  37. *
  38. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  39. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  40. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  41. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  42. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  43. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  44. * DEALINGS IN THE SOFTWARE.
  45. ******************************************************************************
  46. */
  47. /* TODO: update notes in header above */
  48. #include <stdio.h>
  49. #include <assert.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include "tiffio.h"
  53. #include "tif_ovrcache.h"
  54. #ifndef FALSE
  55. # define FALSE 0
  56. # define TRUE 1
  57. #endif
  58. #ifndef MAX
  59. # define MIN(a,b) ((a<b) ? a : b)
  60. # define MAX(a,b) ((a>b) ? a : b)
  61. #endif
  62. void TIFFBuildOverviews( TIFF *, int, int *, int, const char *,
  63. int (*)(double,void*), void * );
  64. /************************************************************************/
  65. /* TIFF_WriteOverview() */
  66. /* */
  67. /* Create a new directory, without any image data for an overview. */
  68. /* Returns offset of newly created overview directory, but the */
  69. /* current directory is reset to be the one in used when this */
  70. /* function is called. */
  71. /************************************************************************/
  72. uint32 TIFF_WriteOverview( TIFF *hTIFF, uint32 nXSize, uint32 nYSize,
  73. int nBitsPerPixel, int nPlanarConfig, int nSamples,
  74. int nBlockXSize, int nBlockYSize,
  75. int bTiled, int nCompressFlag, int nPhotometric,
  76. int nSampleFormat,
  77. unsigned short *panRed,
  78. unsigned short *panGreen,
  79. unsigned short *panBlue,
  80. int bUseSubIFDs,
  81. int nHorSubsampling, int nVerSubsampling )
  82. {
  83. toff_t nBaseDirOffset;
  84. toff_t nOffset;
  85. (void) bUseSubIFDs;
  86. nBaseDirOffset = TIFFCurrentDirOffset( hTIFF );
  87. TIFFCreateDirectory( hTIFF );
  88. /* -------------------------------------------------------------------- */
  89. /* Setup TIFF fields. */
  90. /* -------------------------------------------------------------------- */
  91. TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, nXSize );
  92. TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, nYSize );
  93. if( nSamples == 1 )
  94. TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
  95. else
  96. TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, nPlanarConfig );
  97. TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, nBitsPerPixel );
  98. TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, nSamples );
  99. TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, nCompressFlag );
  100. TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, nPhotometric );
  101. TIFFSetField( hTIFF, TIFFTAG_SAMPLEFORMAT, nSampleFormat );
  102. if( bTiled )
  103. {
  104. TIFFSetField( hTIFF, TIFFTAG_TILEWIDTH, nBlockXSize );
  105. TIFFSetField( hTIFF, TIFFTAG_TILELENGTH, nBlockYSize );
  106. }
  107. else
  108. TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, nBlockYSize );
  109. TIFFSetField( hTIFF, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE );
  110. if( nPhotometric == PHOTOMETRIC_YCBCR || nPhotometric == PHOTOMETRIC_ITULAB )
  111. {
  112. TIFFSetField( hTIFF, TIFFTAG_YCBCRSUBSAMPLING, nHorSubsampling, nVerSubsampling);
  113. /* TODO: also write YCbCrPositioning and YCbCrCoefficients tag identical to source IFD */
  114. }
  115. /* TODO: add command-line parameter for selecting jpeg compression quality
  116. * that gets ignored when compression isn't jpeg */
  117. /* -------------------------------------------------------------------- */
  118. /* Write color table if one is present. */
  119. /* -------------------------------------------------------------------- */
  120. if( panRed != NULL )
  121. {
  122. TIFFSetField( hTIFF, TIFFTAG_COLORMAP, panRed, panGreen, panBlue );
  123. }
  124. /* -------------------------------------------------------------------- */
  125. /* Write directory, and return byte offset. */
  126. /* -------------------------------------------------------------------- */
  127. if( TIFFWriteCheck( hTIFF, bTiled, "TIFFBuildOverviews" ) == 0 )
  128. return 0;
  129. TIFFWriteDirectory( hTIFF );
  130. TIFFSetDirectory( hTIFF, (tdir_t) (TIFFNumberOfDirectories(hTIFF)-1) );
  131. nOffset = TIFFCurrentDirOffset( hTIFF );
  132. TIFFSetSubDirectory( hTIFF, nBaseDirOffset );
  133. return nOffset;
  134. }
  135. /************************************************************************/
  136. /* TIFF_GetSourceSamples() */
  137. /************************************************************************/
  138. static void
  139. TIFF_GetSourceSamples( double * padfSamples, unsigned char *pabySrc,
  140. int nPixelBytes, int nSampleFormat,
  141. uint32 nXSize, uint32 nYSize,
  142. int nPixelOffset, int nLineOffset )
  143. {
  144. uint32 iXOff, iYOff;
  145. int iSample;
  146. iSample = 0;
  147. for( iYOff = 0; iYOff < nYSize; iYOff++ )
  148. {
  149. for( iXOff = 0; iXOff < nXSize; iXOff++ )
  150. {
  151. unsigned char *pabyData;
  152. pabyData = pabySrc + iYOff * nLineOffset + iXOff * nPixelOffset;
  153. if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 1 )
  154. {
  155. padfSamples[iSample++] = *pabyData;
  156. }
  157. else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 2 )
  158. {
  159. padfSamples[iSample++] = ((uint16 *) pabyData)[0];
  160. }
  161. else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 4 )
  162. {
  163. padfSamples[iSample++] = ((uint32 *) pabyData)[0];
  164. }
  165. else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 2 )
  166. {
  167. padfSamples[iSample++] = ((int16 *) pabyData)[0];
  168. }
  169. else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 32 )
  170. {
  171. padfSamples[iSample++] = ((int32 *) pabyData)[0];
  172. }
  173. else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 4 )
  174. {
  175. padfSamples[iSample++] = ((float *) pabyData)[0];
  176. }
  177. else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 8 )
  178. {
  179. padfSamples[iSample++] = ((double *) pabyData)[0];
  180. }
  181. }
  182. }
  183. }
  184. /************************************************************************/
  185. /* TIFF_SetSample() */
  186. /************************************************************************/
  187. static void
  188. TIFF_SetSample( unsigned char * pabyData, int nPixelBytes, int nSampleFormat,
  189. double dfValue )
  190. {
  191. if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 1 )
  192. {
  193. *pabyData = (unsigned char) MAX(0,MIN(255,dfValue));
  194. }
  195. else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 2 )
  196. {
  197. *((uint16 *)pabyData) = (uint16) MAX(0,MIN(65535,dfValue));
  198. }
  199. else if( nSampleFormat == SAMPLEFORMAT_UINT && nPixelBytes == 4 )
  200. {
  201. *((uint32 *)pabyData) = (uint32) dfValue;
  202. }
  203. else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 2 )
  204. {
  205. *((int16 *)pabyData) = (int16) MAX(-32768,MIN(32767,dfValue));
  206. }
  207. else if( nSampleFormat == SAMPLEFORMAT_INT && nPixelBytes == 32 )
  208. {
  209. *((int32 *)pabyData) = (int32) dfValue;
  210. }
  211. else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 4 )
  212. {
  213. *((float *)pabyData) = (float) dfValue;
  214. }
  215. else if( nSampleFormat == SAMPLEFORMAT_IEEEFP && nPixelBytes == 8 )
  216. {
  217. *((double *)pabyData) = dfValue;
  218. }
  219. }
  220. /************************************************************************/
  221. /* TIFF_DownSample() */
  222. /* */
  223. /* Down sample a tile of full res data into a window of a tile */
  224. /* of downsampled data. */
  225. /************************************************************************/
  226. static
  227. void TIFF_DownSample( unsigned char *pabySrcTile,
  228. uint32 nBlockXSize, uint32 nBlockYSize,
  229. int nPixelSkewBits, int nBitsPerPixel,
  230. unsigned char * pabyOTile,
  231. uint32 nOBlockXSize, uint32 nOBlockYSize,
  232. uint32 nTXOff, uint32 nTYOff, int nOMult,
  233. int nSampleFormat, const char * pszResampling )
  234. {
  235. uint32 i, j;
  236. int k, nPixelBytes = (nBitsPerPixel) / 8;
  237. int nPixelGroupBytes = (nBitsPerPixel+nPixelSkewBits)/8;
  238. unsigned char *pabySrc, *pabyDst;
  239. double *padfSamples;
  240. assert( nBitsPerPixel >= 8 );
  241. padfSamples = (double *) malloc(sizeof(double) * nOMult * nOMult);
  242. /* ==================================================================== */
  243. /* Loop over scanline chunks to process, establishing where the */
  244. /* data is going. */
  245. /* ==================================================================== */
  246. for( j = 0; j*nOMult < nBlockYSize; j++ )
  247. {
  248. if( j + nTYOff >= nOBlockYSize )
  249. break;
  250. pabyDst = pabyOTile + ((j+nTYOff)*nOBlockXSize + nTXOff)
  251. * nPixelBytes * nPixelGroupBytes;
  252. /* -------------------------------------------------------------------- */
  253. /* Handler nearest resampling ... we don't even care about the */
  254. /* data type, we just do a bytewise copy. */
  255. /* -------------------------------------------------------------------- */
  256. if( strncmp(pszResampling,"nearest",4) == 0
  257. || strncmp(pszResampling,"NEAR",4) == 0 )
  258. {
  259. pabySrc = pabySrcTile + j*nOMult*nBlockXSize * nPixelGroupBytes;
  260. for( i = 0; i*nOMult < nBlockXSize; i++ )
  261. {
  262. if( i + nTXOff >= nOBlockXSize )
  263. break;
  264. /*
  265. * For now use simple subsampling, from the top left corner
  266. * of the source block of pixels.
  267. */
  268. for( k = 0; k < nPixelBytes; k++ )
  269. pabyDst[k] = pabySrc[k];
  270. pabyDst += nPixelBytes * nPixelGroupBytes;
  271. pabySrc += nOMult * nPixelGroupBytes;
  272. }
  273. }
  274. /* -------------------------------------------------------------------- */
  275. /* Handle the case of averaging. For this we also have to */
  276. /* handle each sample format we are concerned with. */
  277. /* -------------------------------------------------------------------- */
  278. else if( strncmp(pszResampling,"averag",6) == 0
  279. || strncmp(pszResampling,"AVERAG",6) == 0 )
  280. {
  281. pabySrc = pabySrcTile + j*nOMult*nBlockXSize * nPixelGroupBytes;
  282. for( i = 0; i*nOMult < nBlockXSize; i++ )
  283. {
  284. double dfTotal;
  285. uint32 nXSize, nYSize, iSample;
  286. if( i + nTXOff >= nOBlockXSize )
  287. break;
  288. nXSize = MIN((uint32)nOMult,nBlockXSize-i);
  289. nYSize = MIN((uint32)nOMult,nBlockYSize-j);
  290. TIFF_GetSourceSamples( padfSamples, pabySrc,
  291. nPixelBytes, nSampleFormat,
  292. nXSize, nYSize,
  293. nPixelGroupBytes,
  294. nPixelGroupBytes * nBlockXSize );
  295. dfTotal = 0;
  296. for( iSample = 0; iSample < nXSize*nYSize; iSample++ )
  297. {
  298. dfTotal += padfSamples[iSample];
  299. }
  300. TIFF_SetSample( pabyDst, nPixelBytes, nSampleFormat,
  301. dfTotal / (nXSize*nYSize) );
  302. pabySrc += nOMult * nPixelGroupBytes;
  303. pabyDst += nPixelBytes;
  304. }
  305. }
  306. }
  307. free( padfSamples );
  308. }
  309. /************************************************************************/
  310. /* TIFF_DownSample_Subsampled() */
  311. /************************************************************************/
  312. static
  313. void TIFF_DownSample_Subsampled( unsigned char *pabySrcTile, int nSample,
  314. uint32 nBlockXSize, uint32 nBlockYSize,
  315. unsigned char * pabyOTile,
  316. uint32 nOBlockXSize, uint32 nOBlockYSize,
  317. uint32 nTXOff, uint32 nTYOff, int nOMult,
  318. const char *pszResampling,
  319. int nHorSubsampling, int nVerSubsampling )
  320. {
  321. /* TODO: test with variety of subsampling values, and incovinient tile/strip sizes */
  322. int nSampleBlockSize;
  323. int nSourceSampleRowSize;
  324. int nDestSampleRowSize;
  325. uint32 nSourceX, nSourceY;
  326. uint32 nSourceXSec, nSourceYSec;
  327. uint32 nSourceXSecEnd, nSourceYSecEnd;
  328. uint32 nDestX, nDestY;
  329. int nSampleOffsetInSampleBlock;
  330. unsigned int nCummulator;
  331. unsigned int nCummulatorCount;
  332. nSampleBlockSize = nHorSubsampling * nVerSubsampling + 2;
  333. nSourceSampleRowSize =
  334. ( ( nBlockXSize + nHorSubsampling - 1 ) / nHorSubsampling ) * nSampleBlockSize;
  335. nDestSampleRowSize =
  336. ( ( nOBlockXSize + nHorSubsampling - 1 ) / nHorSubsampling ) * nSampleBlockSize;
  337. if( strncmp(pszResampling,"nearest",4) == 0
  338. || strncmp(pszResampling,"NEAR",4) == 0 )
  339. {
  340. if( nSample == 0 )
  341. {
  342. for( nSourceY = 0, nDestY = nTYOff;
  343. nSourceY < nBlockYSize;
  344. nSourceY += nOMult, nDestY ++)
  345. {
  346. if( nDestY >= nOBlockYSize )
  347. break;
  348. for( nSourceX = 0, nDestX = nTXOff;
  349. nSourceX < nBlockXSize;
  350. nSourceX += nOMult, nDestX ++)
  351. {
  352. if( nDestX >= nOBlockXSize )
  353. break;
  354. * ( pabyOTile + ( nDestY / nVerSubsampling ) * nDestSampleRowSize
  355. + ( nDestY % nVerSubsampling ) * nHorSubsampling
  356. + ( nDestX / nHorSubsampling ) * nSampleBlockSize
  357. + ( nDestX % nHorSubsampling ) ) =
  358. * ( pabySrcTile + ( nSourceY / nVerSubsampling ) * nSourceSampleRowSize
  359. + ( nSourceY % nVerSubsampling ) * nHorSubsampling
  360. + ( nSourceX / nHorSubsampling ) * nSampleBlockSize
  361. + ( nSourceX % nHorSubsampling ) );
  362. }
  363. }
  364. }
  365. else
  366. {
  367. nSampleOffsetInSampleBlock = nHorSubsampling * nVerSubsampling + nSample - 1;
  368. for( nSourceY = 0, nDestY = ( nTYOff / nVerSubsampling );
  369. nSourceY < ( nBlockYSize / nVerSubsampling );
  370. nSourceY += nOMult, nDestY ++)
  371. {
  372. if( nDestY*nVerSubsampling >= nOBlockYSize )
  373. break;
  374. for( nSourceX = 0, nDestX = ( nTXOff / nHorSubsampling );
  375. nSourceX < ( nBlockXSize / nHorSubsampling );
  376. nSourceX += nOMult, nDestX ++)
  377. {
  378. if( nDestX*nHorSubsampling >= nOBlockXSize )
  379. break;
  380. * ( pabyOTile + nDestY * nDestSampleRowSize
  381. + nDestX * nSampleBlockSize
  382. + nSampleOffsetInSampleBlock ) =
  383. * ( pabySrcTile + nSourceY * nSourceSampleRowSize
  384. + nSourceX * nSampleBlockSize
  385. + nSampleOffsetInSampleBlock );
  386. }
  387. }
  388. }
  389. }
  390. else if( strncmp(pszResampling,"averag",6) == 0
  391. || strncmp(pszResampling,"AVERAG",6) == 0 )
  392. {
  393. if( nSample == 0 )
  394. {
  395. for( nSourceY = 0, nDestY = nTYOff; nSourceY < nBlockYSize; nSourceY += nOMult, nDestY ++)
  396. {
  397. if( nDestY >= nOBlockYSize )
  398. break;
  399. for( nSourceX = 0, nDestX = nTXOff; nSourceX < nBlockXSize; nSourceX += nOMult, nDestX ++)
  400. {
  401. if( nDestX >= nOBlockXSize )
  402. break;
  403. nSourceXSecEnd = nSourceX + nOMult;
  404. if( nSourceXSecEnd > nBlockXSize )
  405. nSourceXSecEnd = nBlockXSize;
  406. nSourceYSecEnd = nSourceY + nOMult;
  407. if( nSourceYSecEnd > nBlockYSize )
  408. nSourceYSecEnd = nBlockYSize;
  409. nCummulator = 0;
  410. for( nSourceYSec = nSourceY; nSourceYSec < nSourceYSecEnd; nSourceYSec ++)
  411. {
  412. for( nSourceXSec = nSourceX; nSourceXSec < nSourceXSecEnd; nSourceXSec ++)
  413. {
  414. nCummulator += * ( pabySrcTile + ( nSourceYSec / nVerSubsampling ) * nSourceSampleRowSize
  415. + ( nSourceYSec % nVerSubsampling ) * nHorSubsampling
  416. + ( nSourceXSec / nHorSubsampling ) * nSampleBlockSize
  417. + ( nSourceXSec % nHorSubsampling ) );
  418. }
  419. }
  420. nCummulatorCount = ( nSourceXSecEnd - nSourceX ) * ( nSourceYSecEnd - nSourceY );
  421. * ( pabyOTile + ( nDestY / nVerSubsampling ) * nDestSampleRowSize
  422. + ( nDestY % nVerSubsampling ) * nHorSubsampling
  423. + ( nDestX / nHorSubsampling ) * nSampleBlockSize
  424. + ( nDestX % nHorSubsampling ) ) =
  425. ( ( nCummulator + ( nCummulatorCount >> 1 ) ) / nCummulatorCount );
  426. }
  427. }
  428. }
  429. else
  430. {
  431. nSampleOffsetInSampleBlock = nHorSubsampling * nVerSubsampling + nSample - 1;
  432. for( nSourceY = 0, nDestY = ( nTYOff / nVerSubsampling ); nSourceY < ( nBlockYSize / nVerSubsampling );
  433. nSourceY += nOMult, nDestY ++)
  434. {
  435. if( nDestY*nVerSubsampling >= nOBlockYSize )
  436. break;
  437. for( nSourceX = 0, nDestX = ( nTXOff / nHorSubsampling ); nSourceX < ( nBlockXSize / nHorSubsampling );
  438. nSourceX += nOMult, nDestX ++)
  439. {
  440. if( nDestX*nHorSubsampling >= nOBlockXSize )
  441. break;
  442. nSourceXSecEnd = nSourceX + nOMult;
  443. if( nSourceXSecEnd > ( nBlockXSize / nHorSubsampling ) )
  444. nSourceXSecEnd = ( nBlockXSize / nHorSubsampling );
  445. nSourceYSecEnd = nSourceY + nOMult;
  446. if( nSourceYSecEnd > ( nBlockYSize / nVerSubsampling ) )
  447. nSourceYSecEnd = ( nBlockYSize / nVerSubsampling );
  448. nCummulator = 0;
  449. for( nSourceYSec = nSourceY; nSourceYSec < nSourceYSecEnd; nSourceYSec ++)
  450. {
  451. for( nSourceXSec = nSourceX; nSourceXSec < nSourceXSecEnd; nSourceXSec ++)
  452. {
  453. nCummulator += * ( pabySrcTile + nSourceYSec * nSourceSampleRowSize
  454. + nSourceXSec * nSampleBlockSize
  455. + nSampleOffsetInSampleBlock );
  456. }
  457. }
  458. nCummulatorCount = ( nSourceXSecEnd - nSourceX ) * ( nSourceYSecEnd - nSourceY );
  459. * ( pabyOTile + nDestY * nDestSampleRowSize
  460. + nDestX * nSampleBlockSize
  461. + nSampleOffsetInSampleBlock ) =
  462. ( ( nCummulator + ( nCummulatorCount >> 1 ) ) / nCummulatorCount );
  463. }
  464. }
  465. }
  466. }
  467. }
  468. /************************************************************************/
  469. /* TIFF_ProcessFullResBlock() */
  470. /* */
  471. /* Process one block of full res data, downsampling into each */
  472. /* of the overviews. */
  473. /************************************************************************/
  474. void TIFF_ProcessFullResBlock( TIFF *hTIFF, int nPlanarConfig,
  475. int bSubsampled,
  476. int nHorSubsampling, int nVerSubsampling,
  477. int nOverviews, int * panOvList,
  478. int nBitsPerPixel,
  479. int nSamples, TIFFOvrCache ** papoRawBIs,
  480. uint32 nSXOff, uint32 nSYOff,
  481. unsigned char *pabySrcTile,
  482. uint32 nBlockXSize, uint32 nBlockYSize,
  483. int nSampleFormat, const char * pszResampling )
  484. {
  485. int iOverview, iSample;
  486. for( iSample = 0; iSample < nSamples; iSample++ )
  487. {
  488. /*
  489. * We have to read a tile/strip for each sample for
  490. * PLANARCONFIG_SEPARATE. Otherwise, we just read all the samples
  491. * at once when handling the first sample.
  492. */
  493. if( nPlanarConfig == PLANARCONFIG_SEPARATE || iSample == 0 )
  494. {
  495. if( TIFFIsTiled(hTIFF) )
  496. {
  497. TIFFReadEncodedTile( hTIFF,
  498. TIFFComputeTile(hTIFF, nSXOff, nSYOff,
  499. 0, (tsample_t)iSample ),
  500. pabySrcTile,
  501. TIFFTileSize(hTIFF));
  502. }
  503. else
  504. {
  505. TIFFReadEncodedStrip( hTIFF,
  506. TIFFComputeStrip(hTIFF, nSYOff,
  507. (tsample_t) iSample),
  508. pabySrcTile,
  509. TIFFStripSize(hTIFF) );
  510. }
  511. }
  512. /*
  513. * Loop over destination overview layers
  514. */
  515. for( iOverview = 0; iOverview < nOverviews; iOverview++ )
  516. {
  517. TIFFOvrCache *poRBI = papoRawBIs[iOverview];
  518. unsigned char *pabyOTile;
  519. uint32 nTXOff, nTYOff, nOXOff, nOYOff, nOMult;
  520. uint32 nOBlockXSize = poRBI->nBlockXSize;
  521. uint32 nOBlockYSize = poRBI->nBlockYSize;
  522. int nSkewBits, nSampleByteOffset;
  523. /*
  524. * Fetch the destination overview tile
  525. */
  526. nOMult = panOvList[iOverview];
  527. nOXOff = (nSXOff/nOMult) / nOBlockXSize;
  528. nOYOff = (nSYOff/nOMult) / nOBlockYSize;
  529. if( bSubsampled )
  530. {
  531. pabyOTile = TIFFGetOvrBlock_Subsampled( poRBI, nOXOff, nOYOff );
  532. /*
  533. * Establish the offset into this tile at which we should
  534. * start placing data.
  535. */
  536. nTXOff = (nSXOff - nOXOff*nOMult*nOBlockXSize) / nOMult;
  537. nTYOff = (nSYOff - nOYOff*nOMult*nOBlockYSize) / nOMult;
  538. #ifdef DBMALLOC
  539. malloc_chain_check( 1 );
  540. #endif
  541. TIFF_DownSample_Subsampled( pabySrcTile, iSample,
  542. nBlockXSize, nBlockYSize,
  543. pabyOTile,
  544. poRBI->nBlockXSize, poRBI->nBlockYSize,
  545. nTXOff, nTYOff,
  546. nOMult, pszResampling,
  547. nHorSubsampling, nVerSubsampling );
  548. #ifdef DBMALLOC
  549. malloc_chain_check( 1 );
  550. #endif
  551. }
  552. else
  553. {
  554. pabyOTile = TIFFGetOvrBlock( poRBI, nOXOff, nOYOff, iSample );
  555. /*
  556. * Establish the offset into this tile at which we should
  557. * start placing data.
  558. */
  559. nTXOff = (nSXOff - nOXOff*nOMult*nOBlockXSize) / nOMult;
  560. nTYOff = (nSYOff - nOYOff*nOMult*nOBlockYSize) / nOMult;
  561. /*
  562. * Figure out the skew (extra space between ``our samples'') and
  563. * the byte offset to the first sample.
  564. */
  565. assert( (nBitsPerPixel % 8) == 0 );
  566. if( nPlanarConfig == PLANARCONFIG_SEPARATE )
  567. {
  568. nSkewBits = 0;
  569. nSampleByteOffset = 0;
  570. }
  571. else
  572. {
  573. nSkewBits = nBitsPerPixel * (nSamples-1);
  574. nSampleByteOffset = (nBitsPerPixel/8) * iSample;
  575. }
  576. /*
  577. * Perform the downsampling.
  578. */
  579. #ifdef DBMALLOC
  580. malloc_chain_check( 1 );
  581. #endif
  582. TIFF_DownSample( pabySrcTile + nSampleByteOffset,
  583. nBlockXSize, nBlockYSize,
  584. nSkewBits, nBitsPerPixel, pabyOTile,
  585. poRBI->nBlockXSize, poRBI->nBlockYSize,
  586. nTXOff, nTYOff,
  587. nOMult, nSampleFormat, pszResampling );
  588. #ifdef DBMALLOC
  589. malloc_chain_check( 1 );
  590. #endif
  591. }
  592. }
  593. }
  594. }
  595. /************************************************************************/
  596. /* TIFF_BuildOverviews() */
  597. /* */
  598. /* Build the requested list of overviews. Overviews are */
  599. /* maintained in a bunch of temporary files and then these are */
  600. /* written back to the TIFF file. Only one pass through the */
  601. /* source TIFF file is made for any number of output */
  602. /* overviews. */
  603. /************************************************************************/
  604. void TIFFBuildOverviews( TIFF *hTIFF, int nOverviews, int * panOvList,
  605. int bUseSubIFDs, const char *pszResampleMethod,
  606. int (*pfnProgress)( double, void * ),
  607. void * pProgressData )
  608. {
  609. TIFFOvrCache **papoRawBIs;
  610. uint32 nXSize, nYSize, nBlockXSize, nBlockYSize;
  611. uint16 nBitsPerPixel, nPhotometric, nCompressFlag, nSamples,
  612. nPlanarConfig, nSampleFormat;
  613. int bSubsampled;
  614. uint16 nHorSubsampling, nVerSubsampling;
  615. int bTiled, nSXOff, nSYOff, i;
  616. unsigned char *pabySrcTile;
  617. uint16 *panRedMap, *panGreenMap, *panBlueMap;
  618. TIFFErrorHandler pfnWarning;
  619. (void) pfnProgress;
  620. (void) pProgressData;
  621. /* -------------------------------------------------------------------- */
  622. /* Get the base raster size. */
  623. /* -------------------------------------------------------------------- */
  624. TIFFGetField( hTIFF, TIFFTAG_IMAGEWIDTH, &nXSize );
  625. TIFFGetField( hTIFF, TIFFTAG_IMAGELENGTH, &nYSize );
  626. TIFFGetField( hTIFF, TIFFTAG_BITSPERSAMPLE, &nBitsPerPixel );
  627. /* TODO: nBitsPerPixel seems misnomer and may need renaming to nBitsPerSample */
  628. TIFFGetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, &nSamples );
  629. TIFFGetFieldDefaulted( hTIFF, TIFFTAG_PLANARCONFIG, &nPlanarConfig );
  630. TIFFGetFieldDefaulted( hTIFF, TIFFTAG_PHOTOMETRIC, &nPhotometric );
  631. TIFFGetFieldDefaulted( hTIFF, TIFFTAG_COMPRESSION, &nCompressFlag );
  632. TIFFGetFieldDefaulted( hTIFF, TIFFTAG_SAMPLEFORMAT, &nSampleFormat );
  633. if( nPhotometric == PHOTOMETRIC_YCBCR || nPhotometric == PHOTOMETRIC_ITULAB )
  634. {
  635. if( nBitsPerPixel != 8 || nSamples != 3 || nPlanarConfig != PLANARCONFIG_CONTIG ||
  636. nSampleFormat != SAMPLEFORMAT_UINT)
  637. {
  638. /* TODO: use of TIFFError is inconsistent with use of fprintf in addtiffo.c, sort out */
  639. TIFFErrorExt( TIFFClientdata(hTIFF), "TIFFBuildOverviews",
  640. "File `%s' has an unsupported subsampling configuration.\n",
  641. TIFFFileName(hTIFF) );
  642. /* If you need support for this particular flavor, please contact either
  643. * Frank Warmerdam warmerdam@pobox.com
  644. * Joris Van Damme info@awaresystems.be
  645. */
  646. return;
  647. }
  648. bSubsampled = 1;
  649. TIFFGetField( hTIFF, TIFFTAG_YCBCRSUBSAMPLING, &nHorSubsampling, &nVerSubsampling );
  650. /* TODO: find out if maybe TIFFGetFieldDefaulted is better choice for YCbCrSubsampling tag */
  651. }
  652. else
  653. {
  654. if( nBitsPerPixel < 8 )
  655. {
  656. /* TODO: use of TIFFError is inconsistent with use of fprintf in addtiffo.c, sort out */
  657. TIFFErrorExt( TIFFClientdata(hTIFF), "TIFFBuildOverviews",
  658. "File `%s' has samples of %d bits per sample. Sample\n"
  659. "sizes of less than 8 bits per sample are not supported.\n",
  660. TIFFFileName(hTIFF), nBitsPerPixel );
  661. return;
  662. }
  663. bSubsampled = 0;
  664. nHorSubsampling = 1;
  665. nVerSubsampling = 1;
  666. }
  667. /* -------------------------------------------------------------------- */
  668. /* Turn off warnings to avoid alot of repeated warnings while */
  669. /* rereading directories. */
  670. /* -------------------------------------------------------------------- */
  671. pfnWarning = TIFFSetWarningHandler( NULL );
  672. /* -------------------------------------------------------------------- */
  673. /* Get the base raster block size. */
  674. /* -------------------------------------------------------------------- */
  675. if( TIFFGetField( hTIFF, TIFFTAG_ROWSPERSTRIP, &(nBlockYSize) ) )
  676. {
  677. nBlockXSize = nXSize;
  678. bTiled = FALSE;
  679. }
  680. else
  681. {
  682. TIFFGetField( hTIFF, TIFFTAG_TILEWIDTH, &nBlockXSize );
  683. TIFFGetField( hTIFF, TIFFTAG_TILELENGTH, &nBlockYSize );
  684. bTiled = TRUE;
  685. }
  686. /* -------------------------------------------------------------------- */
  687. /* Capture the pallette if there is one. */
  688. /* -------------------------------------------------------------------- */
  689. if( TIFFGetField( hTIFF, TIFFTAG_COLORMAP,
  690. &panRedMap, &panGreenMap, &panBlueMap ) )
  691. {
  692. uint16 *panRed2, *panGreen2, *panBlue2;
  693. int nColorCount = 1 << nBitsPerPixel;
  694. panRed2 = (uint16 *) _TIFFmalloc(2*nColorCount);
  695. panGreen2 = (uint16 *) _TIFFmalloc(2*nColorCount);
  696. panBlue2 = (uint16 *) _TIFFmalloc(2*nColorCount);
  697. memcpy( panRed2, panRedMap, 2 * nColorCount );
  698. memcpy( panGreen2, panGreenMap, 2 * nColorCount );
  699. memcpy( panBlue2, panBlueMap, 2 * nColorCount );
  700. panRedMap = panRed2;
  701. panGreenMap = panGreen2;
  702. panBlueMap = panBlue2;
  703. }
  704. else
  705. {
  706. panRedMap = panGreenMap = panBlueMap = NULL;
  707. }
  708. /* -------------------------------------------------------------------- */
  709. /* Initialize overviews. */
  710. /* -------------------------------------------------------------------- */
  711. papoRawBIs = (TIFFOvrCache **) _TIFFmalloc(nOverviews*sizeof(void*));
  712. for( i = 0; i < nOverviews; i++ )
  713. {
  714. uint32 nOXSize, nOYSize, nOBlockXSize, nOBlockYSize;
  715. toff_t nDirOffset;
  716. nOXSize = (nXSize + panOvList[i] - 1) / panOvList[i];
  717. nOYSize = (nYSize + panOvList[i] - 1) / panOvList[i];
  718. nOBlockXSize = MIN(nBlockXSize,nOXSize);
  719. nOBlockYSize = MIN(nBlockYSize,nOYSize);
  720. if( bTiled )
  721. {
  722. if( (nOBlockXSize % 16) != 0 )
  723. nOBlockXSize = nOBlockXSize + 16 - (nOBlockXSize % 16);
  724. if( (nOBlockYSize % 16) != 0 )
  725. nOBlockYSize = nOBlockYSize + 16 - (nOBlockYSize % 16);
  726. }
  727. nDirOffset = TIFF_WriteOverview( hTIFF, nOXSize, nOYSize,
  728. nBitsPerPixel, nPlanarConfig,
  729. nSamples, nOBlockXSize, nOBlockYSize,
  730. bTiled, nCompressFlag, nPhotometric,
  731. nSampleFormat,
  732. panRedMap, panGreenMap, panBlueMap,
  733. bUseSubIFDs,
  734. nHorSubsampling, nVerSubsampling );
  735. papoRawBIs[i] = TIFFCreateOvrCache( hTIFF, nDirOffset );
  736. }
  737. if( panRedMap != NULL )
  738. {
  739. _TIFFfree( panRedMap );
  740. _TIFFfree( panGreenMap );
  741. _TIFFfree( panBlueMap );
  742. }
  743. /* -------------------------------------------------------------------- */
  744. /* Allocate a buffer to hold a source block. */
  745. /* -------------------------------------------------------------------- */
  746. if( bTiled )
  747. pabySrcTile = (unsigned char *) _TIFFmalloc(TIFFTileSize(hTIFF));
  748. else
  749. pabySrcTile = (unsigned char *) _TIFFmalloc(TIFFStripSize(hTIFF));
  750. /* -------------------------------------------------------------------- */
  751. /* Loop over the source raster, applying data to the */
  752. /* destination raster. */
  753. /* -------------------------------------------------------------------- */
  754. for( nSYOff = 0; nSYOff < (int) nYSize; nSYOff += nBlockYSize )
  755. {
  756. for( nSXOff = 0; nSXOff < (int) nXSize; nSXOff += nBlockXSize )
  757. {
  758. /*
  759. * Read and resample into the various overview images.
  760. */
  761. TIFF_ProcessFullResBlock( hTIFF, nPlanarConfig,
  762. bSubsampled,nHorSubsampling,nVerSubsampling,
  763. nOverviews, panOvList,
  764. nBitsPerPixel, nSamples, papoRawBIs,
  765. nSXOff, nSYOff, pabySrcTile,
  766. nBlockXSize, nBlockYSize,
  767. nSampleFormat, pszResampleMethod );
  768. }
  769. }
  770. _TIFFfree( pabySrcTile );
  771. /* -------------------------------------------------------------------- */
  772. /* Cleanup the rawblockedimage files. */
  773. /* -------------------------------------------------------------------- */
  774. for( i = 0; i < nOverviews; i++ )
  775. {
  776. TIFFDestroyOvrCache( papoRawBIs[i] );
  777. }
  778. if( papoRawBIs != NULL )
  779. _TIFFfree( papoRawBIs );
  780. TIFFSetWarningHandler( pfnWarning );
  781. }
  782. /*
  783. * Local Variables:
  784. * mode: c
  785. * c-basic-offset: 8
  786. * fill-column: 78
  787. * End:
  788. */