tif_luv.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:40k
源码类别:

打印编程

开发平台:

Visual C++

  1. /* $Id: tif_luv.c,v 1.17 2006/03/16 12:38:24 dron Exp $ */
  2. /*
  3.  * Copyright (c) 1997 Greg Ward Larson
  4.  * Copyright (c) 1997 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any
  11.  * advertising or publicity relating to the software without the specific,
  12.  * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE
  19.  * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include "tiffiop.h"
  26. #ifdef LOGLUV_SUPPORT
  27. /*
  28.  * TIFF Library.
  29.  * LogLuv compression support for high dynamic range images.
  30.  *
  31.  * Contributed by Greg Larson.
  32.  *
  33.  * LogLuv image support uses the TIFF library to store 16 or 10-bit
  34.  * log luminance values with 8 bits each of u and v or a 14-bit index.
  35.  *
  36.  * The codec can take as input and produce as output 32-bit IEEE float values 
  37.  * as well as 16-bit integer values.  A 16-bit luminance is interpreted
  38.  * as a sign bit followed by a 15-bit integer that is converted
  39.  * to and from a linear magnitude using the transformation:
  40.  *
  41.  * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit
  42.  *
  43.  * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real
  44.  *
  45.  * The actual conversion to world luminance units in candelas per sq. meter
  46.  * requires an additional multiplier, which is stored in the TIFFTAG_STONITS.
  47.  * This value is usually set such that a reasonable exposure comes from
  48.  * clamping decoded luminances above 1 to 1 in the displayed image.
  49.  *
  50.  * The 16-bit values for u and v may be converted to real values by dividing
  51.  * each by 32768.  (This allows for negative values, which aren't useful as
  52.  * far as we know, but are left in case of future improvements in human
  53.  * color vision.)
  54.  *
  55.  * Conversion from (u,v), which is actually the CIE (u',v') system for
  56.  * you color scientists, is accomplished by the following transformation:
  57.  *
  58.  * u = 4*x / (-2*x + 12*y + 3)
  59.  * v = 9*y / (-2*x + 12*y + 3)
  60.  *
  61.  * x = 9*u / (6*u - 16*v + 12)
  62.  * y = 4*v / (6*u - 16*v + 12)
  63.  *
  64.  * This process is greatly simplified by passing 32-bit IEEE floats
  65.  * for each of three CIE XYZ coordinates.  The codec then takes care
  66.  * of conversion to and from LogLuv, though the application is still
  67.  * responsible for interpreting the TIFFTAG_STONITS calibration factor.
  68.  *
  69.  * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white
  70.  * point of (x,y)=(1/3,1/3).  However, most color systems assume some other
  71.  * white point, such as D65, and an absolute color conversion to XYZ then
  72.  * to another color space with a different white point may introduce an
  73.  * unwanted color cast to the image.  It is often desirable, therefore, to
  74.  * perform a white point conversion that maps the input white to [1 1 1]
  75.  * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT
  76.  * tag value.  A decoder that demands absolute color calibration may use
  77.  * this white point tag to get back the original colors, but usually it
  78.  * will be ignored and the new white point will be used instead that
  79.  * matches the output color space.
  80.  *
  81.  * Pixel information is compressed into one of two basic encodings, depending
  82.  * on the setting of the compression tag, which is one of COMPRESSION_SGILOG
  83.  * or COMPRESSION_SGILOG24.  For COMPRESSION_SGILOG, greyscale data is
  84.  * stored as:
  85.  *
  86.  *  1       15
  87.  * |-+---------------|
  88.  *
  89.  * COMPRESSION_SGILOG color data is stored as:
  90.  *
  91.  *  1       15           8        8
  92.  * |-+---------------|--------+--------|
  93.  *  S       Le           ue       ve
  94.  *
  95.  * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as:
  96.  *
  97.  *      10           14
  98.  * |----------|--------------|
  99.  *      Le'          Ce
  100.  *
  101.  * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is
  102.  * encoded as an index for optimal color resolution.  The 10 log bits are
  103.  * defined by the following conversions:
  104.  *
  105.  * L = 2^((Le'+.5)/64 - 12) # real from 10-bit
  106.  *
  107.  * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real
  108.  *
  109.  * The 10 bits of the smaller format may be converted into the 15 bits of
  110.  * the larger format by multiplying by 4 and adding 13314.  Obviously,
  111.  * a smaller range of magnitudes is covered (about 5 orders of magnitude
  112.  * instead of 38), and the lack of a sign bit means that negative luminances
  113.  * are not allowed.  (Well, they aren't allowed in the real world, either,
  114.  * but they are useful for certain types of image processing.)
  115.  *
  116.  * The desired user format is controlled by the setting the internal
  117.  * pseudo tag TIFFTAG_SGILOGDATAFMT to one of:
  118.  *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float XYZ values
  119.  *  SGILOGDATAFMT_16BIT       = 16-bit integer encodings of logL, u and v
  120.  * Raw data i/o is also possible using:
  121.  *  SGILOGDATAFMT_RAW         = 32-bit unsigned integer with encoded pixel
  122.  * In addition, the following decoding is provided for ease of display:
  123.  *  SGILOGDATAFMT_8BIT        = 8-bit default RGB gamma-corrected values
  124.  *
  125.  * For grayscale images, we provide the following data formats:
  126.  *  SGILOGDATAFMT_FLOAT       = IEEE 32-bit float Y values
  127.  *  SGILOGDATAFMT_16BIT       = 16-bit integer w/ encoded luminance
  128.  *  SGILOGDATAFMT_8BIT        = 8-bit gray monitor values
  129.  *
  130.  * Note that the COMPRESSION_SGILOG applies a simple run-length encoding
  131.  * scheme by separating the logL, u and v bytes for each row and applying
  132.  * a PackBits type of compression.  Since the 24-bit encoding is not
  133.  * adaptive, the 32-bit color format takes less space in many cases.
  134.  *
  135.  * Further control is provided over the conversion from higher-resolution
  136.  * formats to final encoded values through the pseudo tag
  137.  * TIFFTAG_SGILOGENCODE:
  138.  *  SGILOGENCODE_NODITHER     = do not dither encoded values
  139.  *  SGILOGENCODE_RANDITHER    = apply random dithering during encoding
  140.  *
  141.  * The default value of this tag is SGILOGENCODE_NODITHER for
  142.  * COMPRESSION_SGILOG to maximize run-length encoding and
  143.  * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn
  144.  * quantization errors into noise.
  145.  */
  146. #include <stdio.h>
  147. #include <stdlib.h>
  148. #include <math.h>
  149. /*
  150.  * State block for each open TIFF
  151.  * file using LogLuv compression/decompression.
  152.  */
  153. typedef struct logLuvState LogLuvState;
  154. struct logLuvState {
  155. int user_datafmt; /* user data format */
  156. int encode_meth; /* encoding method */
  157. int pixel_size; /* bytes per pixel */
  158. tidata_t* tbuf; /* translation buffer */
  159. int tbuflen; /* buffer length */
  160. void (*tfunc)(LogLuvState*, tidata_t, int);
  161. TIFFVSetMethod vgetparent; /* super-class method */
  162. TIFFVSetMethod vsetparent; /* super-class method */
  163. };
  164. #define DecoderState(tif) ((LogLuvState*) (tif)->tif_data)
  165. #define EncoderState(tif) ((LogLuvState*) (tif)->tif_data)
  166. #define SGILOGDATAFMT_UNKNOWN -1
  167. #define MINRUN 4 /* minimum run length */
  168. /*
  169.  * Decode a string of 16-bit gray pixels.
  170.  */
  171. static int
  172. LogL16Decode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
  173. {
  174. LogLuvState* sp = DecoderState(tif);
  175. int shft, i, npixels;
  176. unsigned char* bp;
  177. int16* tp;
  178. int16 b;
  179. int cc, rc;
  180. assert(s == 0);
  181. assert(sp != NULL);
  182. npixels = occ / sp->pixel_size;
  183. if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
  184. tp = (int16*) op;
  185. else {
  186. assert(sp->tbuflen >= npixels);
  187. tp = (int16*) sp->tbuf;
  188. }
  189. _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0]));
  190. bp = (unsigned char*) tif->tif_rawcp;
  191. cc = tif->tif_rawcc;
  192. /* get each byte string */
  193. for (shft = 2*8; (shft -= 8) >= 0; ) {
  194. for (i = 0; i < npixels && cc > 0; )
  195. if (*bp >= 128) { /* run */
  196. rc = *bp++ + (2-128);
  197. b = (int16)(*bp++ << shft);
  198. cc -= 2;
  199. while (rc-- && i < npixels)
  200. tp[i++] |= b;
  201. } else { /* non-run */
  202. rc = *bp++; /* nul is noop */
  203. while (--cc && rc-- && i < npixels)
  204. tp[i++] |= (int16)*bp++ << shft;
  205. }
  206. if (i != npixels) {
  207. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  208. "LogL16Decode: Not enough data at row %d (short %d pixels)",
  209.     tif->tif_row, npixels - i);
  210. tif->tif_rawcp = (tidata_t) bp;
  211. tif->tif_rawcc = cc;
  212. return (0);
  213. }
  214. }
  215. (*sp->tfunc)(sp, op, npixels);
  216. tif->tif_rawcp = (tidata_t) bp;
  217. tif->tif_rawcc = cc;
  218. return (1);
  219. }
  220. /*
  221.  * Decode a string of 24-bit pixels.
  222.  */
  223. static int
  224. LogLuvDecode24(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
  225. {
  226. LogLuvState* sp = DecoderState(tif);
  227. int cc, i, npixels;
  228. unsigned char* bp;
  229. uint32* tp;
  230. assert(s == 0);
  231. assert(sp != NULL);
  232. npixels = occ / sp->pixel_size;
  233. if (sp->user_datafmt == SGILOGDATAFMT_RAW)
  234. tp = (uint32 *)op;
  235. else {
  236. assert(sp->tbuflen >= npixels);
  237. tp = (uint32 *) sp->tbuf;
  238. }
  239. /* copy to array of uint32 */
  240. bp = (unsigned char*) tif->tif_rawcp;
  241. cc = tif->tif_rawcc;
  242. for (i = 0; i < npixels && cc > 0; i++) {
  243. tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
  244. bp += 3;
  245. cc -= 3;
  246. }
  247. tif->tif_rawcp = (tidata_t) bp;
  248. tif->tif_rawcc = cc;
  249. if (i != npixels) {
  250. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  251.     "LogLuvDecode24: Not enough data at row %d (short %d pixels)",
  252.     tif->tif_row, npixels - i);
  253. return (0);
  254. }
  255. (*sp->tfunc)(sp, op, npixels);
  256. return (1);
  257. }
  258. /*
  259.  * Decode a string of 32-bit pixels.
  260.  */
  261. static int
  262. LogLuvDecode32(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
  263. {
  264. LogLuvState* sp;
  265. int shft, i, npixels;
  266. unsigned char* bp;
  267. uint32* tp;
  268. uint32 b;
  269. int cc, rc;
  270. assert(s == 0);
  271. sp = DecoderState(tif);
  272. assert(sp != NULL);
  273. npixels = occ / sp->pixel_size;
  274. if (sp->user_datafmt == SGILOGDATAFMT_RAW)
  275. tp = (uint32*) op;
  276. else {
  277. assert(sp->tbuflen >= npixels);
  278. tp = (uint32*) sp->tbuf;
  279. }
  280. _TIFFmemset((tdata_t) tp, 0, npixels*sizeof (tp[0]));
  281. bp = (unsigned char*) tif->tif_rawcp;
  282. cc = tif->tif_rawcc;
  283. /* get each byte string */
  284. for (shft = 4*8; (shft -= 8) >= 0; ) {
  285. for (i = 0; i < npixels && cc > 0; )
  286. if (*bp >= 128) { /* run */
  287. rc = *bp++ + (2-128);
  288. b = (uint32)*bp++ << shft;
  289. cc -= 2;
  290. while (rc-- && i < npixels)
  291. tp[i++] |= b;
  292. } else { /* non-run */
  293. rc = *bp++; /* nul is noop */
  294. while (--cc && rc-- && i < npixels)
  295. tp[i++] |= (uint32)*bp++ << shft;
  296. }
  297. if (i != npixels) {
  298. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  299. "LogLuvDecode32: Not enough data at row %d (short %d pixels)",
  300.     tif->tif_row, npixels - i);
  301. tif->tif_rawcp = (tidata_t) bp;
  302. tif->tif_rawcc = cc;
  303. return (0);
  304. }
  305. }
  306. (*sp->tfunc)(sp, op, npixels);
  307. tif->tif_rawcp = (tidata_t) bp;
  308. tif->tif_rawcc = cc;
  309. return (1);
  310. }
  311. /*
  312.  * Decode a strip of pixels.  We break it into rows to
  313.  * maintain synchrony with the encode algorithm, which
  314.  * is row by row.
  315.  */
  316. static int
  317. LogLuvDecodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  318. {
  319. tsize_t rowlen = TIFFScanlineSize(tif);
  320. assert(cc%rowlen == 0);
  321. while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
  322. bp += rowlen, cc -= rowlen;
  323. return (cc == 0);
  324. }
  325. /*
  326.  * Decode a tile of pixels.  We break it into rows to
  327.  * maintain synchrony with the encode algorithm, which
  328.  * is row by row.
  329.  */
  330. static int
  331. LogLuvDecodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  332. {
  333. tsize_t rowlen = TIFFTileRowSize(tif);
  334. assert(cc%rowlen == 0);
  335. while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
  336. bp += rowlen, cc -= rowlen;
  337. return (cc == 0);
  338. }
  339. /*
  340.  * Encode a row of 16-bit pixels.
  341.  */
  342. static int
  343. LogL16Encode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  344. {
  345. LogLuvState* sp = EncoderState(tif);
  346. int shft, i, j, npixels;
  347. tidata_t op;
  348. int16* tp;
  349. int16 b;
  350. int occ, rc=0, mask, beg;
  351. assert(s == 0);
  352. assert(sp != NULL);
  353. npixels = cc / sp->pixel_size;
  354. if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
  355. tp = (int16*) bp;
  356. else {
  357. tp = (int16*) sp->tbuf;
  358. assert(sp->tbuflen >= npixels);
  359. (*sp->tfunc)(sp, bp, npixels);
  360. }
  361. /* compress each byte string */
  362. op = tif->tif_rawcp;
  363. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  364. for (shft = 2*8; (shft -= 8) >= 0; )
  365. for (i = 0; i < npixels; i += rc) {
  366. if (occ < 4) {
  367. tif->tif_rawcp = op;
  368. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  369. if (!TIFFFlushData1(tif))
  370. return (-1);
  371. op = tif->tif_rawcp;
  372. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  373. }
  374. mask = 0xff << shft; /* find next run */
  375. for (beg = i; beg < npixels; beg += rc) {
  376. b = (int16) (tp[beg] & mask);
  377. rc = 1;
  378. while (rc < 127+2 && beg+rc < npixels &&
  379. (tp[beg+rc] & mask) == b)
  380. rc++;
  381. if (rc >= MINRUN)
  382. break; /* long enough */
  383. }
  384. if (beg-i > 1 && beg-i < MINRUN) {
  385. b = (int16) (tp[i] & mask);/*check short run */
  386. j = i+1;
  387. while ((tp[j++] & mask) == b)
  388.                                     if (j == beg) {
  389.                                         *op++ = (tidataval_t)(128-2+j-i);
  390.                                         *op++ = (tidataval_t) (b >> shft);
  391.                                         occ -= 2;
  392.                                         i = beg;
  393.                                         break;
  394.                                     }
  395. }
  396. while (i < beg) { /* write out non-run */
  397. if ((j = beg-i) > 127) j = 127;
  398. if (occ < j+3) {
  399.                                     tif->tif_rawcp = op;
  400.                                     tif->tif_rawcc = tif->tif_rawdatasize - occ;
  401.                                     if (!TIFFFlushData1(tif))
  402.                                         return (-1);
  403.                                     op = tif->tif_rawcp;
  404.                                     occ = tif->tif_rawdatasize - tif->tif_rawcc;
  405. }
  406. *op++ = (tidataval_t) j; occ--;
  407. while (j--) {
  408. *op++ = (tidataval_t) (tp[i++] >> shft & 0xff);
  409. occ--;
  410. }
  411. }
  412. if (rc >= MINRUN) { /* write out run */
  413. *op++ = (tidataval_t) (128-2+rc);
  414. *op++ = (tidataval_t) (tp[beg] >> shft & 0xff);
  415. occ -= 2;
  416. } else
  417. rc = 0;
  418. }
  419. tif->tif_rawcp = op;
  420. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  421. return (0);
  422. }
  423. /*
  424.  * Encode a row of 24-bit pixels.
  425.  */
  426. static int
  427. LogLuvEncode24(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  428. {
  429. LogLuvState* sp = EncoderState(tif);
  430. int i, npixels, occ;
  431. tidata_t op;
  432. uint32* tp;
  433. assert(s == 0);
  434. assert(sp != NULL);
  435. npixels = cc / sp->pixel_size;
  436. if (sp->user_datafmt == SGILOGDATAFMT_RAW)
  437. tp = (uint32*) bp;
  438. else {
  439. tp = (uint32*) sp->tbuf;
  440. assert(sp->tbuflen >= npixels);
  441. (*sp->tfunc)(sp, bp, npixels);
  442. }
  443. /* write out encoded pixels */
  444. op = tif->tif_rawcp;
  445. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  446. for (i = npixels; i--; ) {
  447. if (occ < 3) {
  448. tif->tif_rawcp = op;
  449. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  450. if (!TIFFFlushData1(tif))
  451. return (-1);
  452. op = tif->tif_rawcp;
  453. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  454. }
  455. *op++ = (tidataval_t)(*tp >> 16);
  456. *op++ = (tidataval_t)(*tp >> 8 & 0xff);
  457. *op++ = (tidataval_t)(*tp++ & 0xff);
  458. occ -= 3;
  459. }
  460. tif->tif_rawcp = op;
  461. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  462. return (0);
  463. }
  464. /*
  465.  * Encode a row of 32-bit pixels.
  466.  */
  467. static int
  468. LogLuvEncode32(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  469. {
  470. LogLuvState* sp = EncoderState(tif);
  471. int shft, i, j, npixels;
  472. tidata_t op;
  473. uint32* tp;
  474. uint32 b;
  475. int occ, rc=0, mask, beg;
  476. assert(s == 0);
  477. assert(sp != NULL);
  478. npixels = cc / sp->pixel_size;
  479. if (sp->user_datafmt == SGILOGDATAFMT_RAW)
  480. tp = (uint32*) bp;
  481. else {
  482. tp = (uint32*) sp->tbuf;
  483. assert(sp->tbuflen >= npixels);
  484. (*sp->tfunc)(sp, bp, npixels);
  485. }
  486. /* compress each byte string */
  487. op = tif->tif_rawcp;
  488. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  489. for (shft = 4*8; (shft -= 8) >= 0; )
  490. for (i = 0; i < npixels; i += rc) {
  491. if (occ < 4) {
  492. tif->tif_rawcp = op;
  493. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  494. if (!TIFFFlushData1(tif))
  495. return (-1);
  496. op = tif->tif_rawcp;
  497. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  498. }
  499. mask = 0xff << shft; /* find next run */
  500. for (beg = i; beg < npixels; beg += rc) {
  501. b = tp[beg] & mask;
  502. rc = 1;
  503. while (rc < 127+2 && beg+rc < npixels &&
  504. (tp[beg+rc] & mask) == b)
  505. rc++;
  506. if (rc >= MINRUN)
  507. break; /* long enough */
  508. }
  509. if (beg-i > 1 && beg-i < MINRUN) {
  510. b = tp[i] & mask; /* check short run */
  511. j = i+1;
  512. while ((tp[j++] & mask) == b)
  513. if (j == beg) {
  514. *op++ = (tidataval_t)(128-2+j-i);
  515. *op++ = (tidataval_t)(b >> shft);
  516. occ -= 2;
  517. i = beg;
  518. break;
  519. }
  520. }
  521. while (i < beg) { /* write out non-run */
  522. if ((j = beg-i) > 127) j = 127;
  523. if (occ < j+3) {
  524. tif->tif_rawcp = op;
  525. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  526. if (!TIFFFlushData1(tif))
  527. return (-1);
  528. op = tif->tif_rawcp;
  529. occ = tif->tif_rawdatasize - tif->tif_rawcc;
  530. }
  531. *op++ = (tidataval_t) j; occ--;
  532. while (j--) {
  533. *op++ = (tidataval_t)(tp[i++] >> shft & 0xff);
  534. occ--;
  535. }
  536. }
  537. if (rc >= MINRUN) { /* write out run */
  538. *op++ = (tidataval_t) (128-2+rc);
  539. *op++ = (tidataval_t)(tp[beg] >> shft & 0xff);
  540. occ -= 2;
  541. } else
  542. rc = 0;
  543. }
  544. tif->tif_rawcp = op;
  545. tif->tif_rawcc = tif->tif_rawdatasize - occ;
  546. return (0);
  547. }
  548. /*
  549.  * Encode a strip of pixels.  We break it into rows to
  550.  * avoid encoding runs across row boundaries.
  551.  */
  552. static int
  553. LogLuvEncodeStrip(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  554. {
  555. tsize_t rowlen = TIFFScanlineSize(tif);
  556. assert(cc%rowlen == 0);
  557. while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 0)
  558. bp += rowlen, cc -= rowlen;
  559. return (cc == 0);
  560. }
  561. /*
  562.  * Encode a tile of pixels.  We break it into rows to
  563.  * avoid encoding runs across row boundaries.
  564.  */
  565. static int
  566. LogLuvEncodeTile(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  567. {
  568. tsize_t rowlen = TIFFTileRowSize(tif);
  569. assert(cc%rowlen == 0);
  570. while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 0)
  571. bp += rowlen, cc -= rowlen;
  572. return (cc == 0);
  573. }
  574. /*
  575.  * Encode/Decode functions for converting to and from user formats.
  576.  */
  577. #include "uvcode.h"
  578. #ifndef UVSCALE
  579. #define U_NEU 0.210526316
  580. #define V_NEU 0.473684211
  581. #define UVSCALE 410.
  582. #endif
  583. #ifndef M_LN2
  584. #define M_LN2 0.69314718055994530942
  585. #endif
  586. #ifndef M_PI
  587. #define M_PI 3.14159265358979323846
  588. #endif
  589. #define log2(x) ((1./M_LN2)*log(x))
  590. #define exp2(x) exp(M_LN2*(x))
  591. #define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? 
  592. (int)(x) : 
  593. (int)((x) + rand()*(1./RAND_MAX) - .5))
  594. #if !LOGLUV_PUBLIC
  595. static
  596. #endif
  597. double
  598. LogL16toY(int p16) /* compute luminance from 16-bit LogL */
  599. {
  600. int Le = p16 & 0x7fff;
  601. double Y;
  602. if (!Le)
  603. return (0.);
  604. Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.);
  605. return (!(p16 & 0x8000) ? Y : -Y);
  606. }
  607. #if !LOGLUV_PUBLIC
  608. static
  609. #endif
  610. int
  611. LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
  612. {
  613. if (Y >= 1.8371976e19)
  614. return (0x7fff);
  615. if (Y <= -1.8371976e19)
  616. return (0xffff);
  617. if (Y > 5.4136769e-20)
  618. return itrunc(256.*(log2(Y) + 64.), em);
  619. if (Y < -5.4136769e-20)
  620. return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
  621. return (0);
  622. }
  623. static void
  624. L16toY(LogLuvState* sp, tidata_t op, int n)
  625. {
  626. int16* l16 = (int16*) sp->tbuf;
  627. float* yp = (float*) op;
  628. while (n-- > 0)
  629. *yp++ = (float)LogL16toY(*l16++);
  630. }
  631. static void
  632. L16toGry(LogLuvState* sp, tidata_t op, int n)
  633. {
  634. int16* l16 = (int16*) sp->tbuf;
  635. uint8* gp = (uint8*) op;
  636. while (n-- > 0) {
  637. double Y = LogL16toY(*l16++);
  638. *gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)));
  639. }
  640. }
  641. static void
  642. L16fromY(LogLuvState* sp, tidata_t op, int n)
  643. {
  644. int16* l16 = (int16*) sp->tbuf;
  645. float* yp = (float*) op;
  646. while (n-- > 0)
  647. *l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth));
  648. }
  649. #if !LOGLUV_PUBLIC
  650. static
  651. #endif
  652. void
  653. XYZtoRGB24(float xyz[3], uint8 rgb[3])
  654. {
  655. double r, g, b;
  656. /* assume CCIR-709 primaries */
  657. r =  2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2];
  658. g = -1.022*xyz[0] +  1.978*xyz[1] +  0.044*xyz[2];
  659. b =  0.061*xyz[0] + -0.224*xyz[1] +  1.163*xyz[2];
  660. /* assume 2.0 gamma for speed */
  661. /* could use integer sqrt approx., but this is probably faster */
  662. rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)));
  663. rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)));
  664. rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)));
  665. }
  666. #if !LOGLUV_PUBLIC
  667. static
  668. #endif
  669. double
  670. LogL10toY(int p10) /* compute luminance from 10-bit LogL */
  671. {
  672. if (p10 == 0)
  673. return (0.);
  674. return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.));
  675. }
  676. #if !LOGLUV_PUBLIC
  677. static
  678. #endif
  679. int
  680. LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
  681. {
  682. if (Y >= 15.742)
  683. return (0x3ff);
  684. else if (Y <= .00024283)
  685. return (0);
  686. else
  687. return itrunc(64.*(log2(Y) + 12.), em);
  688. }
  689. #define NANGLES 100
  690. #define uv2ang(u, v) ( (NANGLES*.499999999/M_PI) 
  691. * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES )
  692. static int
  693. oog_encode(double u, double v) /* encode out-of-gamut chroma */
  694. {
  695. static int oog_table[NANGLES];
  696. static int initialized = 0;
  697. register int i;
  698. if (!initialized) { /* set up perimeter table */
  699. double eps[NANGLES], ua, va, ang, epsa;
  700. int ui, vi, ustep;
  701. for (i = NANGLES; i--; )
  702. eps[i] = 2.;
  703. for (vi = UV_NVS; vi--; ) {
  704. va = UV_VSTART + (vi+.5)*UV_SQSIZ;
  705. ustep = uv_row[vi].nus-1;
  706. if (vi == UV_NVS-1 || vi == 0 || ustep <= 0)
  707. ustep = 1;
  708. for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) {
  709. ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
  710. ang = uv2ang(ua, va);
  711.                                 i = (int) ang;
  712. epsa = fabs(ang - (i+.5));
  713. if (epsa < eps[i]) {
  714. oog_table[i] = uv_row[vi].ncum + ui;
  715. eps[i] = epsa;
  716. }
  717. }
  718. }
  719. for (i = NANGLES; i--; ) /* fill any holes */
  720. if (eps[i] > 1.5) {
  721. int i1, i2;
  722. for (i1 = 1; i1 < NANGLES/2; i1++)
  723. if (eps[(i+i1)%NANGLES] < 1.5)
  724. break;
  725. for (i2 = 1; i2 < NANGLES/2; i2++)
  726. if (eps[(i+NANGLES-i2)%NANGLES] < 1.5)
  727. break;
  728. if (i1 < i2)
  729. oog_table[i] =
  730. oog_table[(i+i1)%NANGLES];
  731. else
  732. oog_table[i] =
  733. oog_table[(i+NANGLES-i2)%NANGLES];
  734. }
  735. initialized = 1;
  736. }
  737. i = (int) uv2ang(u, v); /* look up hue angle */
  738. return (oog_table[i]);
  739. }
  740. #undef uv2ang
  741. #undef NANGLES
  742. #if !LOGLUV_PUBLIC
  743. static
  744. #endif
  745. int
  746. uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
  747. {
  748. register int vi, ui;
  749. if (v < UV_VSTART)
  750. return oog_encode(u, v);
  751. vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
  752. if (vi >= UV_NVS)
  753. return oog_encode(u, v);
  754. if (u < uv_row[vi].ustart)
  755. return oog_encode(u, v);
  756. ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
  757. if (ui >= uv_row[vi].nus)
  758. return oog_encode(u, v);
  759. return (uv_row[vi].ncum + ui);
  760. }
  761. #if !LOGLUV_PUBLIC
  762. static
  763. #endif
  764. int
  765. uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
  766. {
  767. int upper, lower;
  768. register int ui, vi;
  769. if (c < 0 || c >= UV_NDIVS)
  770. return (-1);
  771. lower = 0; /* binary search */
  772. upper = UV_NVS;
  773. while (upper - lower > 1) {
  774. vi = (lower + upper) >> 1;
  775. ui = c - uv_row[vi].ncum;
  776. if (ui > 0)
  777. lower = vi;
  778. else if (ui < 0)
  779. upper = vi;
  780. else {
  781. lower = vi;
  782. break;
  783. }
  784. }
  785. vi = lower;
  786. ui = c - uv_row[vi].ncum;
  787. *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
  788. *vp = UV_VSTART + (vi+.5)*UV_SQSIZ;
  789. return (0);
  790. }
  791. #if !LOGLUV_PUBLIC
  792. static
  793. #endif
  794. void
  795. LogLuv24toXYZ(uint32 p, float XYZ[3])
  796. {
  797. int Ce;
  798. double L, u, v, s, x, y;
  799. /* decode luminance */
  800. L = LogL10toY(p>>14 & 0x3ff);
  801. if (L <= 0.) {
  802. XYZ[0] = XYZ[1] = XYZ[2] = 0.;
  803. return;
  804. }
  805. /* decode color */
  806. Ce = p & 0x3fff;
  807. if (uv_decode(&u, &v, Ce) < 0) {
  808. u = U_NEU; v = V_NEU;
  809. }
  810. s = 1./(6.*u - 16.*v + 12.);
  811. x = 9.*u * s;
  812. y = 4.*v * s;
  813. /* convert to XYZ */
  814. XYZ[0] = (float)(x/y * L);
  815. XYZ[1] = (float)L;
  816. XYZ[2] = (float)((1.-x-y)/y * L);
  817. }
  818. #if !LOGLUV_PUBLIC
  819. static
  820. #endif
  821. uint32
  822. LogLuv24fromXYZ(float XYZ[3], int em)
  823. {
  824. int Le, Ce;
  825. double u, v, s;
  826. /* encode luminance */
  827. Le = LogL10fromY(XYZ[1], em);
  828. /* encode color */
  829. s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
  830. if (!Le || s <= 0.) {
  831. u = U_NEU;
  832. v = V_NEU;
  833. } else {
  834. u = 4.*XYZ[0] / s;
  835. v = 9.*XYZ[1] / s;
  836. }
  837. Ce = uv_encode(u, v, em);
  838. if (Ce < 0) /* never happens */
  839. Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
  840. /* combine encodings */
  841. return (Le << 14 | Ce);
  842. }
  843. static void
  844. Luv24toXYZ(LogLuvState* sp, tidata_t op, int n)
  845. {
  846. uint32* luv = (uint32*) sp->tbuf;
  847. float* xyz = (float*) op;
  848. while (n-- > 0) {
  849. LogLuv24toXYZ(*luv, xyz);
  850. xyz += 3;
  851. luv++;
  852. }
  853. }
  854. static void
  855. Luv24toLuv48(LogLuvState* sp, tidata_t op, int n)
  856. {
  857. uint32* luv = (uint32*) sp->tbuf;
  858. int16* luv3 = (int16*) op;
  859. while (n-- > 0) {
  860. double u, v;
  861. *luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314);
  862. if (uv_decode(&u, &v, *luv&0x3fff) < 0) {
  863. u = U_NEU;
  864. v = V_NEU;
  865. }
  866. *luv3++ = (int16)(u * (1L<<15));
  867. *luv3++ = (int16)(v * (1L<<15));
  868. luv++;
  869. }
  870. }
  871. static void
  872. Luv24toRGB(LogLuvState* sp, tidata_t op, int n)
  873. {
  874. uint32* luv = (uint32*) sp->tbuf;
  875. uint8* rgb = (uint8*) op;
  876. while (n-- > 0) {
  877. float xyz[3];
  878. LogLuv24toXYZ(*luv++, xyz);
  879. XYZtoRGB24(xyz, rgb);
  880. rgb += 3;
  881. }
  882. }
  883. static void
  884. Luv24fromXYZ(LogLuvState* sp, tidata_t op, int n)
  885. {
  886. uint32* luv = (uint32*) sp->tbuf;
  887. float* xyz = (float*) op;
  888. while (n-- > 0) {
  889. *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth);
  890. xyz += 3;
  891. }
  892. }
  893. static void
  894. Luv24fromLuv48(LogLuvState* sp, tidata_t op, int n)
  895. {
  896. uint32* luv = (uint32*) sp->tbuf;
  897. int16* luv3 = (int16*) op;
  898. while (n-- > 0) {
  899. int Le, Ce;
  900. if (luv3[0] <= 0)
  901. Le = 0;
  902. else if (luv3[0] >= (1<<12)+3314)
  903. Le = (1<<10) - 1;
  904. else if (sp->encode_meth == SGILOGENCODE_NODITHER)
  905. Le = (luv3[0]-3314) >> 2;
  906. else
  907. Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
  908. Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
  909. sp->encode_meth);
  910. if (Ce < 0) /* never happens */
  911. Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
  912. *luv++ = (uint32)Le << 14 | Ce;
  913. luv3 += 3;
  914. }
  915. }
  916. #if !LOGLUV_PUBLIC
  917. static
  918. #endif
  919. void
  920. LogLuv32toXYZ(uint32 p, float XYZ[3])
  921. {
  922. double L, u, v, s, x, y;
  923. /* decode luminance */
  924. L = LogL16toY((int)p >> 16);
  925. if (L <= 0.) {
  926. XYZ[0] = XYZ[1] = XYZ[2] = 0.;
  927. return;
  928. }
  929. /* decode color */
  930. u = 1./UVSCALE * ((p>>8 & 0xff) + .5);
  931. v = 1./UVSCALE * ((p & 0xff) + .5);
  932. s = 1./(6.*u - 16.*v + 12.);
  933. x = 9.*u * s;
  934. y = 4.*v * s;
  935. /* convert to XYZ */
  936. XYZ[0] = (float)(x/y * L);
  937. XYZ[1] = (float)L;
  938. XYZ[2] = (float)((1.-x-y)/y * L);
  939. }
  940. #if !LOGLUV_PUBLIC
  941. static
  942. #endif
  943. uint32
  944. LogLuv32fromXYZ(float XYZ[3], int em)
  945. {
  946. unsigned int Le, ue, ve;
  947. double u, v, s;
  948. /* encode luminance */
  949. Le = (unsigned int)LogL16fromY(XYZ[1], em);
  950. /* encode color */
  951. s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
  952. if (!Le || s <= 0.) {
  953. u = U_NEU;
  954. v = V_NEU;
  955. } else {
  956. u = 4.*XYZ[0] / s;
  957. v = 9.*XYZ[1] / s;
  958. }
  959. if (u <= 0.) ue = 0;
  960. else ue = itrunc(UVSCALE*u, em);
  961. if (ue > 255) ue = 255;
  962. if (v <= 0.) ve = 0;
  963. else ve = itrunc(UVSCALE*v, em);
  964. if (ve > 255) ve = 255;
  965. /* combine encodings */
  966. return (Le << 16 | ue << 8 | ve);
  967. }
  968. static void
  969. Luv32toXYZ(LogLuvState* sp, tidata_t op, int n)
  970. {
  971. uint32* luv = (uint32*) sp->tbuf;
  972. float* xyz = (float*) op;
  973. while (n-- > 0) {
  974. LogLuv32toXYZ(*luv++, xyz);
  975. xyz += 3;
  976. }
  977. }
  978. static void
  979. Luv32toLuv48(LogLuvState* sp, tidata_t op, int n)
  980. {
  981. uint32* luv = (uint32*) sp->tbuf;
  982. int16* luv3 = (int16*) op;
  983. while (n-- > 0) {
  984. double u, v;
  985. *luv3++ = (int16)(*luv >> 16);
  986. u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5);
  987. v = 1./UVSCALE * ((*luv & 0xff) + .5);
  988. *luv3++ = (int16)(u * (1L<<15));
  989. *luv3++ = (int16)(v * (1L<<15));
  990. luv++;
  991. }
  992. }
  993. static void
  994. Luv32toRGB(LogLuvState* sp, tidata_t op, int n)
  995. {
  996. uint32* luv = (uint32*) sp->tbuf;
  997. uint8* rgb = (uint8*) op;
  998. while (n-- > 0) {
  999. float xyz[3];
  1000. LogLuv32toXYZ(*luv++, xyz);
  1001. XYZtoRGB24(xyz, rgb);
  1002. rgb += 3;
  1003. }
  1004. }
  1005. static void
  1006. Luv32fromXYZ(LogLuvState* sp, tidata_t op, int n)
  1007. {
  1008. uint32* luv = (uint32*) sp->tbuf;
  1009. float* xyz = (float*) op;
  1010. while (n-- > 0) {
  1011. *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);
  1012. xyz += 3;
  1013. }
  1014. }
  1015. static void
  1016. Luv32fromLuv48(LogLuvState* sp, tidata_t op, int n)
  1017. {
  1018. uint32* luv = (uint32*) sp->tbuf;
  1019. int16* luv3 = (int16*) op;
  1020. if (sp->encode_meth == SGILOGENCODE_NODITHER) {
  1021. while (n-- > 0) {
  1022. *luv++ = (uint32)luv3[0] << 16 |
  1023. (luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) |
  1024. (luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff);
  1025. luv3 += 3;
  1026. }
  1027. return;
  1028. }
  1029. while (n-- > 0) {
  1030. *luv++ = (uint32)luv3[0] << 16 |
  1031. (itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
  1032. (itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
  1033. luv3 += 3;
  1034. }
  1035. }
  1036. static void
  1037. _logLuvNop(LogLuvState* sp, tidata_t op, int n)
  1038. {
  1039. (void) sp; (void) op; (void) n;
  1040. }
  1041. static int
  1042. LogL16GuessDataFmt(TIFFDirectory *td)
  1043. {
  1044. #define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f))
  1045. switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) {
  1046. case PACK(1, 32, SAMPLEFORMAT_IEEEFP):
  1047. return (SGILOGDATAFMT_FLOAT);
  1048. case PACK(1, 16, SAMPLEFORMAT_VOID):
  1049. case PACK(1, 16, SAMPLEFORMAT_INT):
  1050. case PACK(1, 16, SAMPLEFORMAT_UINT):
  1051. return (SGILOGDATAFMT_16BIT);
  1052. case PACK(1,  8, SAMPLEFORMAT_VOID):
  1053. case PACK(1,  8, SAMPLEFORMAT_UINT):
  1054. return (SGILOGDATAFMT_8BIT);
  1055. }
  1056. #undef PACK
  1057. return (SGILOGDATAFMT_UNKNOWN);
  1058. }
  1059. static uint32
  1060. multiply(size_t m1, size_t m2)
  1061. {
  1062. uint32 bytes = m1 * m2;
  1063. if (m1 && bytes / m1 != m2)
  1064. bytes = 0;
  1065. return bytes;
  1066. }
  1067. static int
  1068. LogL16InitState(TIFF* tif)
  1069. {
  1070. TIFFDirectory *td = &tif->tif_dir;
  1071. LogLuvState* sp = DecoderState(tif);
  1072. static const char module[] = "LogL16InitState";
  1073. assert(sp != NULL);
  1074. assert(td->td_photometric == PHOTOMETRIC_LOGL);
  1075. /* for some reason, we can't do this in TIFFInitLogL16 */
  1076. if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
  1077. sp->user_datafmt = LogL16GuessDataFmt(td);
  1078. switch (sp->user_datafmt) {
  1079. case SGILOGDATAFMT_FLOAT:
  1080. sp->pixel_size = sizeof (float);
  1081. break;
  1082. case SGILOGDATAFMT_16BIT:
  1083. sp->pixel_size = sizeof (int16);
  1084. break;
  1085. case SGILOGDATAFMT_8BIT:
  1086. sp->pixel_size = sizeof (uint8);
  1087. break;
  1088. default:
  1089. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1090.     "No support for converting user data format to LogL");
  1091. return (0);
  1092. }
  1093. sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip);
  1094. if (multiply(sp->tbuflen, sizeof (int16)) == 0 ||
  1095.     (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
  1096. TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for SGILog translation buffer",
  1097.     tif->tif_name);
  1098. return (0);
  1099. }
  1100. return (1);
  1101. }
  1102. static int
  1103. LogLuvGuessDataFmt(TIFFDirectory *td)
  1104. {
  1105. int guess;
  1106. /*
  1107.  * If the user didn't tell us their datafmt,
  1108.  * take our best guess from the bitspersample.
  1109.  */
  1110. #define PACK(a,b) (((a)<<3)|(b))
  1111. switch (PACK(td->td_bitspersample, td->td_sampleformat)) {
  1112. case PACK(32, SAMPLEFORMAT_IEEEFP):
  1113. guess = SGILOGDATAFMT_FLOAT;
  1114. break;
  1115. case PACK(32, SAMPLEFORMAT_VOID):
  1116. case PACK(32, SAMPLEFORMAT_UINT):
  1117. case PACK(32, SAMPLEFORMAT_INT):
  1118. guess = SGILOGDATAFMT_RAW;
  1119. break;
  1120. case PACK(16, SAMPLEFORMAT_VOID):
  1121. case PACK(16, SAMPLEFORMAT_INT):
  1122. case PACK(16, SAMPLEFORMAT_UINT):
  1123. guess = SGILOGDATAFMT_16BIT;
  1124. break;
  1125. case PACK( 8, SAMPLEFORMAT_VOID):
  1126. case PACK( 8, SAMPLEFORMAT_UINT):
  1127. guess = SGILOGDATAFMT_8BIT;
  1128. break;
  1129. default:
  1130. guess = SGILOGDATAFMT_UNKNOWN;
  1131. break;
  1132. #undef PACK
  1133. }
  1134. /*
  1135.  * Double-check samples per pixel.
  1136.  */
  1137. switch (td->td_samplesperpixel) {
  1138. case 1:
  1139. if (guess != SGILOGDATAFMT_RAW)
  1140. guess = SGILOGDATAFMT_UNKNOWN;
  1141. break;
  1142. case 3:
  1143. if (guess == SGILOGDATAFMT_RAW)
  1144. guess = SGILOGDATAFMT_UNKNOWN;
  1145. break;
  1146. default:
  1147. guess = SGILOGDATAFMT_UNKNOWN;
  1148. break;
  1149. }
  1150. return (guess);
  1151. }
  1152. static int
  1153. LogLuvInitState(TIFF* tif)
  1154. {
  1155. TIFFDirectory* td = &tif->tif_dir;
  1156. LogLuvState* sp = DecoderState(tif);
  1157. static const char module[] = "LogLuvInitState";
  1158. assert(sp != NULL);
  1159. assert(td->td_photometric == PHOTOMETRIC_LOGLUV);
  1160. /* for some reason, we can't do this in TIFFInitLogLuv */
  1161. if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
  1162. TIFFErrorExt(tif->tif_clientdata, module,
  1163.     "SGILog compression cannot handle non-contiguous data");
  1164. return (0);
  1165. }
  1166. if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
  1167. sp->user_datafmt = LogLuvGuessDataFmt(td);
  1168. switch (sp->user_datafmt) {
  1169. case SGILOGDATAFMT_FLOAT:
  1170. sp->pixel_size = 3*sizeof (float);
  1171. break;
  1172. case SGILOGDATAFMT_16BIT:
  1173. sp->pixel_size = 3*sizeof (int16);
  1174. break;
  1175. case SGILOGDATAFMT_RAW:
  1176. sp->pixel_size = sizeof (uint32);
  1177. break;
  1178. case SGILOGDATAFMT_8BIT:
  1179. sp->pixel_size = 3*sizeof (uint8);
  1180. break;
  1181. default:
  1182. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1183.     "No support for converting user data format to LogLuv");
  1184. return (0);
  1185. }
  1186. sp->tbuflen = multiply(td->td_imagewidth, td->td_rowsperstrip);
  1187. if (multiply(sp->tbuflen, sizeof (uint32)) == 0 ||
  1188.     (sp->tbuf = (tidata_t*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
  1189. TIFFErrorExt(tif->tif_clientdata, module, "%s: No space for SGILog translation buffer",
  1190.     tif->tif_name);
  1191. return (0);
  1192. }
  1193. return (1);
  1194. }
  1195. static int
  1196. LogLuvSetupDecode(TIFF* tif)
  1197. {
  1198. LogLuvState* sp = DecoderState(tif);
  1199. TIFFDirectory* td = &tif->tif_dir;
  1200. tif->tif_postdecode = _TIFFNoPostDecode;
  1201. switch (td->td_photometric) {
  1202. case PHOTOMETRIC_LOGLUV:
  1203. if (!LogLuvInitState(tif))
  1204. break;
  1205. if (td->td_compression == COMPRESSION_SGILOG24) {
  1206. tif->tif_decoderow = LogLuvDecode24;
  1207. switch (sp->user_datafmt) {
  1208. case SGILOGDATAFMT_FLOAT:
  1209. sp->tfunc = Luv24toXYZ;
  1210. break;
  1211. case SGILOGDATAFMT_16BIT:
  1212. sp->tfunc = Luv24toLuv48;
  1213. break;
  1214. case SGILOGDATAFMT_8BIT:
  1215. sp->tfunc = Luv24toRGB;
  1216. break;
  1217. }
  1218. } else {
  1219. tif->tif_decoderow = LogLuvDecode32;
  1220. switch (sp->user_datafmt) {
  1221. case SGILOGDATAFMT_FLOAT:
  1222. sp->tfunc = Luv32toXYZ;
  1223. break;
  1224. case SGILOGDATAFMT_16BIT:
  1225. sp->tfunc = Luv32toLuv48;
  1226. break;
  1227. case SGILOGDATAFMT_8BIT:
  1228. sp->tfunc = Luv32toRGB;
  1229. break;
  1230. }
  1231. }
  1232. return (1);
  1233. case PHOTOMETRIC_LOGL:
  1234. if (!LogL16InitState(tif))
  1235. break;
  1236. tif->tif_decoderow = LogL16Decode;
  1237. switch (sp->user_datafmt) {
  1238. case SGILOGDATAFMT_FLOAT:
  1239. sp->tfunc = L16toY;
  1240. break;
  1241. case SGILOGDATAFMT_8BIT:
  1242. sp->tfunc = L16toGry;
  1243. break;
  1244. }
  1245. return (1);
  1246. default:
  1247. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1248.     "Inappropriate photometric interpretation %d for SGILog compression; %s",
  1249.     td->td_photometric, "must be either LogLUV or LogL");
  1250. break;
  1251. }
  1252. return (0);
  1253. }
  1254. static int
  1255. LogLuvSetupEncode(TIFF* tif)
  1256. {
  1257. LogLuvState* sp = EncoderState(tif);
  1258. TIFFDirectory* td = &tif->tif_dir;
  1259. switch (td->td_photometric) {
  1260. case PHOTOMETRIC_LOGLUV:
  1261. if (!LogLuvInitState(tif))
  1262. break;
  1263. if (td->td_compression == COMPRESSION_SGILOG24) {
  1264. tif->tif_encoderow = LogLuvEncode24;
  1265. switch (sp->user_datafmt) {
  1266. case SGILOGDATAFMT_FLOAT:
  1267. sp->tfunc = Luv24fromXYZ;
  1268. break;
  1269. case SGILOGDATAFMT_16BIT:
  1270. sp->tfunc = Luv24fromLuv48;
  1271. break;
  1272. case SGILOGDATAFMT_RAW:
  1273. break;
  1274. default:
  1275. goto notsupported;
  1276. }
  1277. } else {
  1278. tif->tif_encoderow = LogLuvEncode32;
  1279. switch (sp->user_datafmt) {
  1280. case SGILOGDATAFMT_FLOAT:
  1281. sp->tfunc = Luv32fromXYZ;
  1282. break;
  1283. case SGILOGDATAFMT_16BIT:
  1284. sp->tfunc = Luv32fromLuv48;
  1285. break;
  1286. case SGILOGDATAFMT_RAW:
  1287. break;
  1288. default:
  1289. goto notsupported;
  1290. }
  1291. }
  1292. break;
  1293. case PHOTOMETRIC_LOGL:
  1294. if (!LogL16InitState(tif))
  1295. break;
  1296. tif->tif_encoderow = LogL16Encode;
  1297. switch (sp->user_datafmt) {
  1298. case SGILOGDATAFMT_FLOAT:
  1299. sp->tfunc = L16fromY;
  1300. break;
  1301. case SGILOGDATAFMT_16BIT:
  1302. break;
  1303. default:
  1304. goto notsupported;
  1305. }
  1306. break;
  1307. default:
  1308. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1309.     "Inappropriate photometric interpretation %d for SGILog compression; %s",
  1310.          td->td_photometric, "must be either LogLUV or LogL");
  1311. break;
  1312. }
  1313. return (1);
  1314. notsupported:
  1315. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1316.     "SGILog compression supported only for %s, or raw data",
  1317.     td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
  1318. return (0);
  1319. }
  1320. static void
  1321. LogLuvClose(TIFF* tif)
  1322. {
  1323. TIFFDirectory *td = &tif->tif_dir;
  1324. /*
  1325.  * For consistency, we always want to write out the same
  1326.  * bitspersample and sampleformat for our TIFF file,
  1327.  * regardless of the data format being used by the application.
  1328.  * Since this routine is called after tags have been set but
  1329.  * before they have been recorded in the file, we reset them here.
  1330.  */
  1331. td->td_samplesperpixel =
  1332.     (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
  1333. td->td_bitspersample = 16;
  1334. td->td_sampleformat = SAMPLEFORMAT_INT;
  1335. }
  1336. static void
  1337. LogLuvCleanup(TIFF* tif)
  1338. {
  1339. LogLuvState* sp = (LogLuvState *)tif->tif_data;
  1340. assert(sp != 0);
  1341. tif->tif_tagmethods.vgetfield = sp->vgetparent;
  1342. tif->tif_tagmethods.vsetfield = sp->vsetparent;
  1343. if (sp->tbuf)
  1344. _TIFFfree(sp->tbuf);
  1345. _TIFFfree(sp);
  1346. tif->tif_data = NULL;
  1347. _TIFFSetDefaultCompressionState(tif);
  1348. }
  1349. static int
  1350. LogLuvVSetField(TIFF* tif, ttag_t tag, va_list ap)
  1351. {
  1352. LogLuvState* sp = DecoderState(tif);
  1353. int bps, fmt;
  1354. switch (tag) {
  1355. case TIFFTAG_SGILOGDATAFMT:
  1356. sp->user_datafmt = va_arg(ap, int);
  1357. /*
  1358.  * Tweak the TIFF header so that the rest of libtiff knows what
  1359.  * size of data will be passed between app and library, and
  1360.  * assume that the app knows what it is doing and is not
  1361.  * confused by these header manipulations...
  1362.  */
  1363. switch (sp->user_datafmt) {
  1364. case SGILOGDATAFMT_FLOAT:
  1365. bps = 32, fmt = SAMPLEFORMAT_IEEEFP;
  1366. break;
  1367. case SGILOGDATAFMT_16BIT:
  1368. bps = 16, fmt = SAMPLEFORMAT_INT;
  1369. break;
  1370. case SGILOGDATAFMT_RAW:
  1371. bps = 32, fmt = SAMPLEFORMAT_UINT;
  1372. TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
  1373. break;
  1374. case SGILOGDATAFMT_8BIT:
  1375. bps = 8, fmt = SAMPLEFORMAT_UINT;
  1376. break;
  1377. default:
  1378. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1379.     "Unknown data format %d for LogLuv compression",
  1380.     sp->user_datafmt);
  1381. return (0);
  1382. }
  1383. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
  1384. TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);
  1385. /*
  1386.  * Must recalculate sizes should bits/sample change.
  1387.  */
  1388. tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
  1389. tif->tif_scanlinesize = TIFFScanlineSize(tif);
  1390. return (1);
  1391. case TIFFTAG_SGILOGENCODE:
  1392. sp->encode_meth = va_arg(ap, int);
  1393. if (sp->encode_meth != SGILOGENCODE_NODITHER &&
  1394. sp->encode_meth != SGILOGENCODE_RANDITHER) {
  1395. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1396. "Unknown encoding %d for LogLuv compression",
  1397. sp->encode_meth);
  1398. return (0);
  1399. }
  1400. return (1);
  1401. default:
  1402. return (*sp->vsetparent)(tif, tag, ap);
  1403. }
  1404. }
  1405. static int
  1406. LogLuvVGetField(TIFF* tif, ttag_t tag, va_list ap)
  1407. {
  1408. LogLuvState *sp = (LogLuvState *)tif->tif_data;
  1409. switch (tag) {
  1410. case TIFFTAG_SGILOGDATAFMT:
  1411. *va_arg(ap, int*) = sp->user_datafmt;
  1412. return (1);
  1413. default:
  1414. return (*sp->vgetparent)(tif, tag, ap);
  1415. }
  1416. }
  1417. static const TIFFFieldInfo LogLuvFieldInfo[] = {
  1418.     { TIFFTAG_SGILOGDATAFMT,   0, 0, TIFF_SHORT, FIELD_PSEUDO,
  1419.       TRUE, FALSE, "SGILogDataFmt"},
  1420.     { TIFFTAG_SGILOGENCODE,   0, 0, TIFF_SHORT, FIELD_PSEUDO,
  1421.       TRUE, FALSE, "SGILogEncode"}
  1422. };
  1423. int
  1424. TIFFInitSGILog(TIFF* tif, int scheme)
  1425. {
  1426. static const char module[] = "TIFFInitSGILog";
  1427. LogLuvState* sp;
  1428. assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);
  1429. /*
  1430.  * Allocate state block so tag methods have storage to record values.
  1431.  */
  1432. tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (LogLuvState));
  1433. if (tif->tif_data == NULL)
  1434. goto bad;
  1435. sp = (LogLuvState*) tif->tif_data;
  1436. _TIFFmemset((tdata_t)sp, 0, sizeof (*sp));
  1437. sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;
  1438. sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ?
  1439. SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER;
  1440. sp->tfunc = _logLuvNop;
  1441. /*
  1442.  * Install codec methods.
  1443.  * NB: tif_decoderow & tif_encoderow are filled
  1444.  *     in at setup time.
  1445.  */
  1446. tif->tif_setupdecode = LogLuvSetupDecode;
  1447. tif->tif_decodestrip = LogLuvDecodeStrip;
  1448. tif->tif_decodetile = LogLuvDecodeTile;
  1449. tif->tif_setupencode = LogLuvSetupEncode;
  1450. tif->tif_encodestrip = LogLuvEncodeStrip;
  1451. tif->tif_encodetile = LogLuvEncodeTile;
  1452. tif->tif_close = LogLuvClose;
  1453. tif->tif_cleanup = LogLuvCleanup;
  1454. /* override SetField so we can handle our private pseudo-tag */
  1455. _TIFFMergeFieldInfo(tif, LogLuvFieldInfo,
  1456.     TIFFArrayCount(LogLuvFieldInfo));
  1457. sp->vgetparent = tif->tif_tagmethods.vgetfield;
  1458. tif->tif_tagmethods.vgetfield = LogLuvVGetField;   /* hook for codec tags */
  1459. sp->vsetparent = tif->tif_tagmethods.vsetfield;
  1460. tif->tif_tagmethods.vsetfield = LogLuvVSetField;   /* hook for codec tags */
  1461. return (1);
  1462. bad:
  1463. TIFFErrorExt(tif->tif_clientdata, module,
  1464.      "%s: No space for LogLuv state block", tif->tif_name);
  1465. return (0);
  1466. }
  1467. #endif /* LOGLUV_SUPPORT */
  1468. /* vim: set ts=8 sts=8 sw=8 noet: */