/src/FreeImage/Source/LibTIFF/tif_pixarlog.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 1371 lines · 1074 code · 124 blank · 173 comment · 222 complexity · 1f38fddd16ac4780af495479bb4e9ea6 MD5 · raw file

  1. /* $Id: tif_pixarlog.c,v 1.37 2011/04/10 17:14:09 drolon Exp $ */
  2. /*
  3. * Copyright (c) 1996-1997 Sam Leffler
  4. * Copyright (c) 1996 Pixar
  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. * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or
  11. * publicity relating to the software without the specific, prior written
  12. * permission of Pixar, Sam Leffler 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 PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19. * 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 PIXARLOG_SUPPORT
  27. /*
  28. * TIFF Library.
  29. * PixarLog Compression Support
  30. *
  31. * Contributed by Dan McCoy.
  32. *
  33. * PixarLog film support uses the TIFF library to store companded
  34. * 11 bit values into a tiff file, which are compressed using the
  35. * zip compressor.
  36. *
  37. * The codec can take as input and produce as output 32-bit IEEE float values
  38. * as well as 16-bit or 8-bit unsigned integer values.
  39. *
  40. * On writing any of the above are converted into the internal
  41. * 11-bit log format. In the case of 8 and 16 bit values, the
  42. * input is assumed to be unsigned linear color values that represent
  43. * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to
  44. * be the normal linear color range, in addition over 1 values are
  45. * accepted up to a value of about 25.0 to encode "hot" hightlights and such.
  46. * The encoding is lossless for 8-bit values, slightly lossy for the
  47. * other bit depths. The actual color precision should be better
  48. * than the human eye can perceive with extra room to allow for
  49. * error introduced by further image computation. As with any quantized
  50. * color format, it is possible to perform image calculations which
  51. * expose the quantization error. This format should certainly be less
  52. * susceptable to such errors than standard 8-bit encodings, but more
  53. * susceptable than straight 16-bit or 32-bit encodings.
  54. *
  55. * On reading the internal format is converted to the desired output format.
  56. * The program can request which format it desires by setting the internal
  57. * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
  58. * PIXARLOGDATAFMT_FLOAT = provide IEEE float values.
  59. * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values
  60. * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values
  61. *
  62. * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
  63. * values with the difference that if there are exactly three or four channels
  64. * (rgb or rgba) it swaps the channel order (bgr or abgr).
  65. *
  66. * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
  67. * packed in 16-bit values. However no tools are supplied for interpreting
  68. * these values.
  69. *
  70. * "hot" (over 1.0) areas written in floating point get clamped to
  71. * 1.0 in the integer data types.
  72. *
  73. * When the file is closed after writing, the bit depth and sample format
  74. * are set always to appear as if 8-bit data has been written into it.
  75. * That way a naive program unaware of the particulars of the encoding
  76. * gets the format it is most likely able to handle.
  77. *
  78. * The codec does it's own horizontal differencing step on the coded
  79. * values so the libraries predictor stuff should be turned off.
  80. * The codec also handle byte swapping the encoded values as necessary
  81. * since the library does not have the information necessary
  82. * to know the bit depth of the raw unencoded buffer.
  83. *
  84. */
  85. #include "tif_predict.h"
  86. #include "../ZLib/zlib.h"
  87. #include <stdio.h>
  88. #include <stdlib.h>
  89. #include <math.h>
  90. /* Tables for converting to/from 11 bit coded values */
  91. #define TSIZE 2048 /* decode table size (11-bit tokens) */
  92. #define TSIZEP1 2049 /* Plus one for slop */
  93. #define ONE 1250 /* token value of 1.0 exactly */
  94. #define RATIO 1.004 /* nominal ratio for log part */
  95. #define CODE_MASK 0x7ff /* 11 bits. */
  96. static float Fltsize;
  97. static float LogK1, LogK2;
  98. #define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); }
  99. static void
  100. horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
  101. float *ToLinearF)
  102. {
  103. register unsigned int cr, cg, cb, ca, mask;
  104. register float t0, t1, t2, t3;
  105. if (n >= stride) {
  106. mask = CODE_MASK;
  107. if (stride == 3) {
  108. t0 = ToLinearF[cr = wp[0]];
  109. t1 = ToLinearF[cg = wp[1]];
  110. t2 = ToLinearF[cb = wp[2]];
  111. op[0] = t0;
  112. op[1] = t1;
  113. op[2] = t2;
  114. n -= 3;
  115. while (n > 0) {
  116. wp += 3;
  117. op += 3;
  118. n -= 3;
  119. t0 = ToLinearF[(cr += wp[0]) & mask];
  120. t1 = ToLinearF[(cg += wp[1]) & mask];
  121. t2 = ToLinearF[(cb += wp[2]) & mask];
  122. op[0] = t0;
  123. op[1] = t1;
  124. op[2] = t2;
  125. }
  126. } else if (stride == 4) {
  127. t0 = ToLinearF[cr = wp[0]];
  128. t1 = ToLinearF[cg = wp[1]];
  129. t2 = ToLinearF[cb = wp[2]];
  130. t3 = ToLinearF[ca = wp[3]];
  131. op[0] = t0;
  132. op[1] = t1;
  133. op[2] = t2;
  134. op[3] = t3;
  135. n -= 4;
  136. while (n > 0) {
  137. wp += 4;
  138. op += 4;
  139. n -= 4;
  140. t0 = ToLinearF[(cr += wp[0]) & mask];
  141. t1 = ToLinearF[(cg += wp[1]) & mask];
  142. t2 = ToLinearF[(cb += wp[2]) & mask];
  143. t3 = ToLinearF[(ca += wp[3]) & mask];
  144. op[0] = t0;
  145. op[1] = t1;
  146. op[2] = t2;
  147. op[3] = t3;
  148. }
  149. } else {
  150. REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
  151. n -= stride;
  152. while (n > 0) {
  153. REPEAT(stride,
  154. wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
  155. n -= stride;
  156. }
  157. }
  158. }
  159. }
  160. static void
  161. horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
  162. float *ToLinearF)
  163. {
  164. register unsigned int cr, cg, cb, ca, mask;
  165. register float t0, t1, t2, t3;
  166. #define SCALE12 2048.0F
  167. #define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
  168. if (n >= stride) {
  169. mask = CODE_MASK;
  170. if (stride == 3) {
  171. t0 = ToLinearF[cr = wp[0]] * SCALE12;
  172. t1 = ToLinearF[cg = wp[1]] * SCALE12;
  173. t2 = ToLinearF[cb = wp[2]] * SCALE12;
  174. op[0] = CLAMP12(t0);
  175. op[1] = CLAMP12(t1);
  176. op[2] = CLAMP12(t2);
  177. n -= 3;
  178. while (n > 0) {
  179. wp += 3;
  180. op += 3;
  181. n -= 3;
  182. t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
  183. t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
  184. t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
  185. op[0] = CLAMP12(t0);
  186. op[1] = CLAMP12(t1);
  187. op[2] = CLAMP12(t2);
  188. }
  189. } else if (stride == 4) {
  190. t0 = ToLinearF[cr = wp[0]] * SCALE12;
  191. t1 = ToLinearF[cg = wp[1]] * SCALE12;
  192. t2 = ToLinearF[cb = wp[2]] * SCALE12;
  193. t3 = ToLinearF[ca = wp[3]] * SCALE12;
  194. op[0] = CLAMP12(t0);
  195. op[1] = CLAMP12(t1);
  196. op[2] = CLAMP12(t2);
  197. op[3] = CLAMP12(t3);
  198. n -= 4;
  199. while (n > 0) {
  200. wp += 4;
  201. op += 4;
  202. n -= 4;
  203. t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
  204. t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
  205. t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
  206. t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
  207. op[0] = CLAMP12(t0);
  208. op[1] = CLAMP12(t1);
  209. op[2] = CLAMP12(t2);
  210. op[3] = CLAMP12(t3);
  211. }
  212. } else {
  213. REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
  214. *op = CLAMP12(t0); wp++; op++)
  215. n -= stride;
  216. while (n > 0) {
  217. REPEAT(stride,
  218. wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
  219. *op = CLAMP12(t0); wp++; op++)
  220. n -= stride;
  221. }
  222. }
  223. }
  224. }
  225. static void
  226. horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
  227. uint16 *ToLinear16)
  228. {
  229. register unsigned int cr, cg, cb, ca, mask;
  230. if (n >= stride) {
  231. mask = CODE_MASK;
  232. if (stride == 3) {
  233. op[0] = ToLinear16[cr = wp[0]];
  234. op[1] = ToLinear16[cg = wp[1]];
  235. op[2] = ToLinear16[cb = wp[2]];
  236. n -= 3;
  237. while (n > 0) {
  238. wp += 3;
  239. op += 3;
  240. n -= 3;
  241. op[0] = ToLinear16[(cr += wp[0]) & mask];
  242. op[1] = ToLinear16[(cg += wp[1]) & mask];
  243. op[2] = ToLinear16[(cb += wp[2]) & mask];
  244. }
  245. } else if (stride == 4) {
  246. op[0] = ToLinear16[cr = wp[0]];
  247. op[1] = ToLinear16[cg = wp[1]];
  248. op[2] = ToLinear16[cb = wp[2]];
  249. op[3] = ToLinear16[ca = wp[3]];
  250. n -= 4;
  251. while (n > 0) {
  252. wp += 4;
  253. op += 4;
  254. n -= 4;
  255. op[0] = ToLinear16[(cr += wp[0]) & mask];
  256. op[1] = ToLinear16[(cg += wp[1]) & mask];
  257. op[2] = ToLinear16[(cb += wp[2]) & mask];
  258. op[3] = ToLinear16[(ca += wp[3]) & mask];
  259. }
  260. } else {
  261. REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
  262. n -= stride;
  263. while (n > 0) {
  264. REPEAT(stride,
  265. wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
  266. n -= stride;
  267. }
  268. }
  269. }
  270. }
  271. /*
  272. * Returns the log encoded 11-bit values with the horizontal
  273. * differencing undone.
  274. */
  275. static void
  276. horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
  277. {
  278. register unsigned int cr, cg, cb, ca, mask;
  279. if (n >= stride) {
  280. mask = CODE_MASK;
  281. if (stride == 3) {
  282. op[0] = cr = wp[0]; op[1] = cg = wp[1]; op[2] = cb = wp[2];
  283. n -= 3;
  284. while (n > 0) {
  285. wp += 3;
  286. op += 3;
  287. n -= 3;
  288. op[0] = (cr += wp[0]) & mask;
  289. op[1] = (cg += wp[1]) & mask;
  290. op[2] = (cb += wp[2]) & mask;
  291. }
  292. } else if (stride == 4) {
  293. op[0] = cr = wp[0]; op[1] = cg = wp[1];
  294. op[2] = cb = wp[2]; op[3] = ca = wp[3];
  295. n -= 4;
  296. while (n > 0) {
  297. wp += 4;
  298. op += 4;
  299. n -= 4;
  300. op[0] = (cr += wp[0]) & mask;
  301. op[1] = (cg += wp[1]) & mask;
  302. op[2] = (cb += wp[2]) & mask;
  303. op[3] = (ca += wp[3]) & mask;
  304. }
  305. } else {
  306. REPEAT(stride, *op = *wp&mask; wp++; op++)
  307. n -= stride;
  308. while (n > 0) {
  309. REPEAT(stride,
  310. wp[stride] += *wp; *op = *wp&mask; wp++; op++)
  311. n -= stride;
  312. }
  313. }
  314. }
  315. }
  316. static void
  317. horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
  318. unsigned char *ToLinear8)
  319. {
  320. register unsigned int cr, cg, cb, ca, mask;
  321. if (n >= stride) {
  322. mask = CODE_MASK;
  323. if (stride == 3) {
  324. op[0] = ToLinear8[cr = wp[0]];
  325. op[1] = ToLinear8[cg = wp[1]];
  326. op[2] = ToLinear8[cb = wp[2]];
  327. n -= 3;
  328. while (n > 0) {
  329. n -= 3;
  330. wp += 3;
  331. op += 3;
  332. op[0] = ToLinear8[(cr += wp[0]) & mask];
  333. op[1] = ToLinear8[(cg += wp[1]) & mask];
  334. op[2] = ToLinear8[(cb += wp[2]) & mask];
  335. }
  336. } else if (stride == 4) {
  337. op[0] = ToLinear8[cr = wp[0]];
  338. op[1] = ToLinear8[cg = wp[1]];
  339. op[2] = ToLinear8[cb = wp[2]];
  340. op[3] = ToLinear8[ca = wp[3]];
  341. n -= 4;
  342. while (n > 0) {
  343. n -= 4;
  344. wp += 4;
  345. op += 4;
  346. op[0] = ToLinear8[(cr += wp[0]) & mask];
  347. op[1] = ToLinear8[(cg += wp[1]) & mask];
  348. op[2] = ToLinear8[(cb += wp[2]) & mask];
  349. op[3] = ToLinear8[(ca += wp[3]) & mask];
  350. }
  351. } else {
  352. REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
  353. n -= stride;
  354. while (n > 0) {
  355. REPEAT(stride,
  356. wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
  357. n -= stride;
  358. }
  359. }
  360. }
  361. }
  362. static void
  363. horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
  364. unsigned char *ToLinear8)
  365. {
  366. register unsigned int cr, cg, cb, ca, mask;
  367. register unsigned char t0, t1, t2, t3;
  368. if (n >= stride) {
  369. mask = CODE_MASK;
  370. if (stride == 3) {
  371. op[0] = 0;
  372. t1 = ToLinear8[cb = wp[2]];
  373. t2 = ToLinear8[cg = wp[1]];
  374. t3 = ToLinear8[cr = wp[0]];
  375. op[1] = t1;
  376. op[2] = t2;
  377. op[3] = t3;
  378. n -= 3;
  379. while (n > 0) {
  380. n -= 3;
  381. wp += 3;
  382. op += 4;
  383. op[0] = 0;
  384. t1 = ToLinear8[(cb += wp[2]) & mask];
  385. t2 = ToLinear8[(cg += wp[1]) & mask];
  386. t3 = ToLinear8[(cr += wp[0]) & mask];
  387. op[1] = t1;
  388. op[2] = t2;
  389. op[3] = t3;
  390. }
  391. } else if (stride == 4) {
  392. t0 = ToLinear8[ca = wp[3]];
  393. t1 = ToLinear8[cb = wp[2]];
  394. t2 = ToLinear8[cg = wp[1]];
  395. t3 = ToLinear8[cr = wp[0]];
  396. op[0] = t0;
  397. op[1] = t1;
  398. op[2] = t2;
  399. op[3] = t3;
  400. n -= 4;
  401. while (n > 0) {
  402. n -= 4;
  403. wp += 4;
  404. op += 4;
  405. t0 = ToLinear8[(ca += wp[3]) & mask];
  406. t1 = ToLinear8[(cb += wp[2]) & mask];
  407. t2 = ToLinear8[(cg += wp[1]) & mask];
  408. t3 = ToLinear8[(cr += wp[0]) & mask];
  409. op[0] = t0;
  410. op[1] = t1;
  411. op[2] = t2;
  412. op[3] = t3;
  413. }
  414. } else {
  415. REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
  416. n -= stride;
  417. while (n > 0) {
  418. REPEAT(stride,
  419. wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
  420. n -= stride;
  421. }
  422. }
  423. }
  424. }
  425. /*
  426. * State block for each open TIFF
  427. * file using PixarLog compression/decompression.
  428. */
  429. typedef struct {
  430. TIFFPredictorState predict;
  431. z_stream stream;
  432. uint16 *tbuf;
  433. uint16 stride;
  434. int state;
  435. int user_datafmt;
  436. int quality;
  437. #define PLSTATE_INIT 1
  438. TIFFVSetMethod vgetparent; /* super-class method */
  439. TIFFVSetMethod vsetparent; /* super-class method */
  440. float *ToLinearF;
  441. uint16 *ToLinear16;
  442. unsigned char *ToLinear8;
  443. uint16 *FromLT2;
  444. uint16 *From14; /* Really for 16-bit data, but we shift down 2 */
  445. uint16 *From8;
  446. } PixarLogState;
  447. static int
  448. PixarLogMakeTables(PixarLogState *sp)
  449. {
  450. /*
  451. * We make several tables here to convert between various external
  452. * representations (float, 16-bit, and 8-bit) and the internal
  453. * 11-bit companded representation. The 11-bit representation has two
  454. * distinct regions. A linear bottom end up through .018316 in steps
  455. * of about .000073, and a region of constant ratio up to about 25.
  456. * These floating point numbers are stored in the main table ToLinearF.
  457. * All other tables are derived from this one. The tables (and the
  458. * ratios) are continuous at the internal seam.
  459. */
  460. int nlin, lt2size;
  461. int i, j;
  462. double b, c, linstep, v;
  463. float *ToLinearF;
  464. uint16 *ToLinear16;
  465. unsigned char *ToLinear8;
  466. uint16 *FromLT2;
  467. uint16 *From14; /* Really for 16-bit data, but we shift down 2 */
  468. uint16 *From8;
  469. c = log(RATIO);
  470. nlin = (int)(1./c); /* nlin must be an integer */
  471. c = 1./nlin;
  472. b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */
  473. linstep = b*c*exp(1.);
  474. LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */
  475. LogK2 = (float)(1./b);
  476. lt2size = (int)(2./linstep) + 1;
  477. FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
  478. From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
  479. From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
  480. ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
  481. ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
  482. ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
  483. if (FromLT2 == NULL || From14 == NULL || From8 == NULL ||
  484. ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
  485. if (FromLT2) _TIFFfree(FromLT2);
  486. if (From14) _TIFFfree(From14);
  487. if (From8) _TIFFfree(From8);
  488. if (ToLinearF) _TIFFfree(ToLinearF);
  489. if (ToLinear16) _TIFFfree(ToLinear16);
  490. if (ToLinear8) _TIFFfree(ToLinear8);
  491. sp->FromLT2 = NULL;
  492. sp->From14 = NULL;
  493. sp->From8 = NULL;
  494. sp->ToLinearF = NULL;
  495. sp->ToLinear16 = NULL;
  496. sp->ToLinear8 = NULL;
  497. return 0;
  498. }
  499. j = 0;
  500. for (i = 0; i < nlin; i++) {
  501. v = i * linstep;
  502. ToLinearF[j++] = (float)v;
  503. }
  504. for (i = nlin; i < TSIZE; i++)
  505. ToLinearF[j++] = (float)(b*exp(c*i));
  506. ToLinearF[2048] = ToLinearF[2047];
  507. for (i = 0; i < TSIZEP1; i++) {
  508. v = ToLinearF[i]*65535.0 + 0.5;
  509. ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
  510. v = ToLinearF[i]*255.0 + 0.5;
  511. ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
  512. }
  513. j = 0;
  514. for (i = 0; i < lt2size; i++) {
  515. if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
  516. j++;
  517. FromLT2[i] = j;
  518. }
  519. /*
  520. * Since we lose info anyway on 16-bit data, we set up a 14-bit
  521. * table and shift 16-bit values down two bits on input.
  522. * saves a little table space.
  523. */
  524. j = 0;
  525. for (i = 0; i < 16384; i++) {
  526. while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
  527. j++;
  528. From14[i] = j;
  529. }
  530. j = 0;
  531. for (i = 0; i < 256; i++) {
  532. while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
  533. j++;
  534. From8[i] = j;
  535. }
  536. Fltsize = (float)(lt2size/2);
  537. sp->ToLinearF = ToLinearF;
  538. sp->ToLinear16 = ToLinear16;
  539. sp->ToLinear8 = ToLinear8;
  540. sp->FromLT2 = FromLT2;
  541. sp->From14 = From14;
  542. sp->From8 = From8;
  543. return 1;
  544. }
  545. #define DecoderState(tif) ((PixarLogState*) (tif)->tif_data)
  546. #define EncoderState(tif) ((PixarLogState*) (tif)->tif_data)
  547. static int PixarLogEncode(TIFF*, tidata_t, tsize_t, tsample_t);
  548. static int PixarLogDecode(TIFF*, tidata_t, tsize_t, tsample_t);
  549. #define PIXARLOGDATAFMT_UNKNOWN -1
  550. static int
  551. PixarLogGuessDataFmt(TIFFDirectory *td)
  552. {
  553. int guess = PIXARLOGDATAFMT_UNKNOWN;
  554. int format = td->td_sampleformat;
  555. /* If the user didn't tell us his datafmt,
  556. * take our best guess from the bitspersample.
  557. */
  558. switch (td->td_bitspersample) {
  559. case 32:
  560. if (format == SAMPLEFORMAT_IEEEFP)
  561. guess = PIXARLOGDATAFMT_FLOAT;
  562. break;
  563. case 16:
  564. if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
  565. guess = PIXARLOGDATAFMT_16BIT;
  566. break;
  567. case 12:
  568. if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
  569. guess = PIXARLOGDATAFMT_12BITPICIO;
  570. break;
  571. case 11:
  572. if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
  573. guess = PIXARLOGDATAFMT_11BITLOG;
  574. break;
  575. case 8:
  576. if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
  577. guess = PIXARLOGDATAFMT_8BIT;
  578. break;
  579. }
  580. return guess;
  581. }
  582. static uint32
  583. multiply(size_t m1, size_t m2)
  584. {
  585. uint32 bytes = m1 * m2;
  586. if (m1 && bytes / m1 != m2)
  587. bytes = 0;
  588. return bytes;
  589. }
  590. static int
  591. PixarLogSetupDecode(TIFF* tif)
  592. {
  593. TIFFDirectory *td = &tif->tif_dir;
  594. PixarLogState* sp = DecoderState(tif);
  595. tsize_t tbuf_size;
  596. static const char module[] = "PixarLogSetupDecode";
  597. assert(sp != NULL);
  598. /* Make sure no byte swapping happens on the data
  599. * after decompression. */
  600. tif->tif_postdecode = _TIFFNoPostDecode;
  601. /* for some reason, we can't do this in TIFFInitPixarLog */
  602. sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
  603. td->td_samplesperpixel : 1);
  604. tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth),
  605. td->td_rowsperstrip), sizeof(uint16));
  606. if (tbuf_size == 0)
  607. return (0);
  608. sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
  609. if (sp->tbuf == NULL)
  610. return (0);
  611. if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
  612. sp->user_datafmt = PixarLogGuessDataFmt(td);
  613. if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
  614. TIFFErrorExt(tif->tif_clientdata, module,
  615. "PixarLog compression can't handle bits depth/data format combination (depth: %d)",
  616. td->td_bitspersample);
  617. return (0);
  618. }
  619. if (inflateInit(&sp->stream) != Z_OK) {
  620. TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
  621. return (0);
  622. } else {
  623. sp->state |= PLSTATE_INIT;
  624. return (1);
  625. }
  626. }
  627. /*
  628. * Setup state for decoding a strip.
  629. */
  630. static int
  631. PixarLogPreDecode(TIFF* tif, tsample_t s)
  632. {
  633. PixarLogState* sp = DecoderState(tif);
  634. (void) s;
  635. assert(sp != NULL);
  636. sp->stream.next_in = tif->tif_rawdata;
  637. sp->stream.avail_in = tif->tif_rawcc;
  638. return (inflateReset(&sp->stream) == Z_OK);
  639. }
  640. static int
  641. PixarLogDecode(TIFF* tif, tidata_t op, tsize_t occ, tsample_t s)
  642. {
  643. TIFFDirectory *td = &tif->tif_dir;
  644. PixarLogState* sp = DecoderState(tif);
  645. static const char module[] = "PixarLogDecode";
  646. int i, nsamples, llen;
  647. uint16 *up;
  648. switch (sp->user_datafmt) {
  649. case PIXARLOGDATAFMT_FLOAT:
  650. nsamples = occ / sizeof(float); /* XXX float == 32 bits */
  651. break;
  652. case PIXARLOGDATAFMT_16BIT:
  653. case PIXARLOGDATAFMT_12BITPICIO:
  654. case PIXARLOGDATAFMT_11BITLOG:
  655. nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
  656. break;
  657. case PIXARLOGDATAFMT_8BIT:
  658. case PIXARLOGDATAFMT_8BITABGR:
  659. nsamples = occ;
  660. break;
  661. default:
  662. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  663. "%d bit input not supported in PixarLog",
  664. td->td_bitspersample);
  665. return 0;
  666. }
  667. llen = sp->stride * td->td_imagewidth;
  668. (void) s;
  669. assert(sp != NULL);
  670. sp->stream.next_out = (unsigned char *) sp->tbuf;
  671. sp->stream.avail_out = nsamples * sizeof(uint16);
  672. do {
  673. int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
  674. if (state == Z_STREAM_END) {
  675. break; /* XXX */
  676. }
  677. if (state == Z_DATA_ERROR) {
  678. TIFFErrorExt(tif->tif_clientdata, module,
  679. "%s: Decoding error at scanline %d, %s",
  680. tif->tif_name, tif->tif_row, sp->stream.msg);
  681. if (inflateSync(&sp->stream) != Z_OK)
  682. return (0);
  683. continue;
  684. }
  685. if (state != Z_OK) {
  686. TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
  687. tif->tif_name, sp->stream.msg);
  688. return (0);
  689. }
  690. } while (sp->stream.avail_out > 0);
  691. /* hopefully, we got all the bytes we needed */
  692. if (sp->stream.avail_out != 0) {
  693. TIFFErrorExt(tif->tif_clientdata, module,
  694. "%s: Not enough data at scanline %d (short %d bytes)",
  695. tif->tif_name, tif->tif_row, sp->stream.avail_out);
  696. return (0);
  697. }
  698. up = sp->tbuf;
  699. /* Swap bytes in the data if from a different endian machine. */
  700. if (tif->tif_flags & TIFF_SWAB)
  701. TIFFSwabArrayOfShort(up, nsamples);
  702. /*
  703. * if llen is not an exact multiple of nsamples, the decode operation
  704. * may overflow the output buffer, so truncate it enough to prevent
  705. * that but still salvage as much data as possible.
  706. */
  707. if (nsamples % llen) {
  708. TIFFWarningExt(tif->tif_clientdata, module,
  709. "%s: stride %d is not a multiple of sample count, "
  710. "%d, data truncated.", tif->tif_name, llen, nsamples);
  711. nsamples -= nsamples % llen;
  712. }
  713. for (i = 0; i < nsamples; i += llen, up += llen) {
  714. switch (sp->user_datafmt) {
  715. case PIXARLOGDATAFMT_FLOAT:
  716. horizontalAccumulateF(up, llen, sp->stride,
  717. (float *)op, sp->ToLinearF);
  718. op += llen * sizeof(float);
  719. break;
  720. case PIXARLOGDATAFMT_16BIT:
  721. horizontalAccumulate16(up, llen, sp->stride,
  722. (uint16 *)op, sp->ToLinear16);
  723. op += llen * sizeof(uint16);
  724. break;
  725. case PIXARLOGDATAFMT_12BITPICIO:
  726. horizontalAccumulate12(up, llen, sp->stride,
  727. (int16 *)op, sp->ToLinearF);
  728. op += llen * sizeof(int16);
  729. break;
  730. case PIXARLOGDATAFMT_11BITLOG:
  731. horizontalAccumulate11(up, llen, sp->stride,
  732. (uint16 *)op);
  733. op += llen * sizeof(uint16);
  734. break;
  735. case PIXARLOGDATAFMT_8BIT:
  736. horizontalAccumulate8(up, llen, sp->stride,
  737. (unsigned char *)op, sp->ToLinear8);
  738. op += llen * sizeof(unsigned char);
  739. break;
  740. case PIXARLOGDATAFMT_8BITABGR:
  741. horizontalAccumulate8abgr(up, llen, sp->stride,
  742. (unsigned char *)op, sp->ToLinear8);
  743. op += llen * sizeof(unsigned char);
  744. break;
  745. default:
  746. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  747. "PixarLogDecode: unsupported bits/sample: %d",
  748. td->td_bitspersample);
  749. return (0);
  750. }
  751. }
  752. return (1);
  753. }
  754. static int
  755. PixarLogSetupEncode(TIFF* tif)
  756. {
  757. TIFFDirectory *td = &tif->tif_dir;
  758. PixarLogState* sp = EncoderState(tif);
  759. tsize_t tbuf_size;
  760. static const char module[] = "PixarLogSetupEncode";
  761. assert(sp != NULL);
  762. /* for some reason, we can't do this in TIFFInitPixarLog */
  763. sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
  764. td->td_samplesperpixel : 1);
  765. tbuf_size = multiply(multiply(multiply(sp->stride, td->td_imagewidth),
  766. td->td_rowsperstrip), sizeof(uint16));
  767. if (tbuf_size == 0)
  768. return (0);
  769. sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
  770. if (sp->tbuf == NULL)
  771. return (0);
  772. if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
  773. sp->user_datafmt = PixarLogGuessDataFmt(td);
  774. if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
  775. TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
  776. return (0);
  777. }
  778. if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
  779. TIFFErrorExt(tif->tif_clientdata, module, "%s: %s", tif->tif_name, sp->stream.msg);
  780. return (0);
  781. } else {
  782. sp->state |= PLSTATE_INIT;
  783. return (1);
  784. }
  785. }
  786. /*
  787. * Reset encoding state at the start of a strip.
  788. */
  789. static int
  790. PixarLogPreEncode(TIFF* tif, tsample_t s)
  791. {
  792. PixarLogState *sp = EncoderState(tif);
  793. (void) s;
  794. assert(sp != NULL);
  795. sp->stream.next_out = tif->tif_rawdata;
  796. sp->stream.avail_out = tif->tif_rawdatasize;
  797. return (deflateReset(&sp->stream) == Z_OK);
  798. }
  799. static void
  800. horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
  801. {
  802. int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
  803. float fltsize = Fltsize;
  804. #define CLAMP(v) ( (v<(float)0.) ? 0 \
  805. : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \
  806. : (v>(float)24.2) ? 2047 \
  807. : LogK1*log(v*LogK2) + 0.5 )
  808. mask = CODE_MASK;
  809. if (n >= stride) {
  810. if (stride == 3) {
  811. r2 = wp[0] = (uint16) CLAMP(ip[0]);
  812. g2 = wp[1] = (uint16) CLAMP(ip[1]);
  813. b2 = wp[2] = (uint16) CLAMP(ip[2]);
  814. n -= 3;
  815. while (n > 0) {
  816. n -= 3;
  817. wp += 3;
  818. ip += 3;
  819. r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
  820. g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
  821. b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
  822. }
  823. } else if (stride == 4) {
  824. r2 = wp[0] = (uint16) CLAMP(ip[0]);
  825. g2 = wp[1] = (uint16) CLAMP(ip[1]);
  826. b2 = wp[2] = (uint16) CLAMP(ip[2]);
  827. a2 = wp[3] = (uint16) CLAMP(ip[3]);
  828. n -= 4;
  829. while (n > 0) {
  830. n -= 4;
  831. wp += 4;
  832. ip += 4;
  833. r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
  834. g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
  835. b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
  836. a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
  837. }
  838. } else {
  839. ip += n - 1; /* point to last one */
  840. wp += n - 1; /* point to last one */
  841. n -= stride;
  842. while (n > 0) {
  843. REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
  844. wp[stride] -= wp[0];
  845. wp[stride] &= mask;
  846. wp--; ip--)
  847. n -= stride;
  848. }
  849. REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
  850. }
  851. }
  852. }
  853. static void
  854. horizontalDifference16(unsigned short *ip, int n, int stride,
  855. unsigned short *wp, uint16 *From14)
  856. {
  857. register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
  858. /* assumption is unsigned pixel values */
  859. #undef CLAMP
  860. #define CLAMP(v) From14[(v) >> 2]
  861. mask = CODE_MASK;
  862. if (n >= stride) {
  863. if (stride == 3) {
  864. r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
  865. b2 = wp[2] = CLAMP(ip[2]);
  866. n -= 3;
  867. while (n > 0) {
  868. n -= 3;
  869. wp += 3;
  870. ip += 3;
  871. r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
  872. g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
  873. b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
  874. }
  875. } else if (stride == 4) {
  876. r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
  877. b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
  878. n -= 4;
  879. while (n > 0) {
  880. n -= 4;
  881. wp += 4;
  882. ip += 4;
  883. r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
  884. g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
  885. b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
  886. a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
  887. }
  888. } else {
  889. ip += n - 1; /* point to last one */
  890. wp += n - 1; /* point to last one */
  891. n -= stride;
  892. while (n > 0) {
  893. REPEAT(stride, wp[0] = CLAMP(ip[0]);
  894. wp[stride] -= wp[0];
  895. wp[stride] &= mask;
  896. wp--; ip--)
  897. n -= stride;
  898. }
  899. REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
  900. }
  901. }
  902. }
  903. static void
  904. horizontalDifference8(unsigned char *ip, int n, int stride,
  905. unsigned short *wp, uint16 *From8)
  906. {
  907. register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
  908. #undef CLAMP
  909. #define CLAMP(v) (From8[(v)])
  910. mask = CODE_MASK;
  911. if (n >= stride) {
  912. if (stride == 3) {
  913. r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
  914. b2 = wp[2] = CLAMP(ip[2]);
  915. n -= 3;
  916. while (n > 0) {
  917. n -= 3;
  918. r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
  919. g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
  920. b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
  921. wp += 3;
  922. ip += 3;
  923. }
  924. } else if (stride == 4) {
  925. r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
  926. b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
  927. n -= 4;
  928. while (n > 0) {
  929. n -= 4;
  930. r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
  931. g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
  932. b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
  933. a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
  934. wp += 4;
  935. ip += 4;
  936. }
  937. } else {
  938. wp += n + stride - 1; /* point to last one */
  939. ip += n + stride - 1; /* point to last one */
  940. n -= stride;
  941. while (n > 0) {
  942. REPEAT(stride, wp[0] = CLAMP(ip[0]);
  943. wp[stride] -= wp[0];
  944. wp[stride] &= mask;
  945. wp--; ip--)
  946. n -= stride;
  947. }
  948. REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
  949. }
  950. }
  951. }
  952. /*
  953. * Encode a chunk of pixels.
  954. */
  955. static int
  956. PixarLogEncode(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  957. {
  958. TIFFDirectory *td = &tif->tif_dir;
  959. PixarLogState *sp = EncoderState(tif);
  960. static const char module[] = "PixarLogEncode";
  961. int i, n, llen;
  962. unsigned short * up;
  963. (void) s;
  964. switch (sp->user_datafmt) {
  965. case PIXARLOGDATAFMT_FLOAT:
  966. n = cc / sizeof(float); /* XXX float == 32 bits */
  967. break;
  968. case PIXARLOGDATAFMT_16BIT:
  969. case PIXARLOGDATAFMT_12BITPICIO:
  970. case PIXARLOGDATAFMT_11BITLOG:
  971. n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */
  972. break;
  973. case PIXARLOGDATAFMT_8BIT:
  974. case PIXARLOGDATAFMT_8BITABGR:
  975. n = cc;
  976. break;
  977. default:
  978. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  979. "%d bit input not supported in PixarLog",
  980. td->td_bitspersample);
  981. return 0;
  982. }
  983. llen = sp->stride * td->td_imagewidth;
  984. for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
  985. switch (sp->user_datafmt) {
  986. case PIXARLOGDATAFMT_FLOAT:
  987. horizontalDifferenceF((float *)bp, llen,
  988. sp->stride, up, sp->FromLT2);
  989. bp += llen * sizeof(float);
  990. break;
  991. case PIXARLOGDATAFMT_16BIT:
  992. horizontalDifference16((uint16 *)bp, llen,
  993. sp->stride, up, sp->From14);
  994. bp += llen * sizeof(uint16);
  995. break;
  996. case PIXARLOGDATAFMT_8BIT:
  997. horizontalDifference8((unsigned char *)bp, llen,
  998. sp->stride, up, sp->From8);
  999. bp += llen * sizeof(unsigned char);
  1000. break;
  1001. default:
  1002. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  1003. "%d bit input not supported in PixarLog",
  1004. td->td_bitspersample);
  1005. return 0;
  1006. }
  1007. }
  1008. sp->stream.next_in = (unsigned char *) sp->tbuf;
  1009. sp->stream.avail_in = n * sizeof(uint16);
  1010. do {
  1011. if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
  1012. TIFFErrorExt(tif->tif_clientdata, module, "%s: Encoder error: %s",
  1013. tif->tif_name, sp->stream.msg);
  1014. return (0);
  1015. }
  1016. if (sp->stream.avail_out == 0) {
  1017. tif->tif_rawcc = tif->tif_rawdatasize;
  1018. TIFFFlushData1(tif);
  1019. sp->stream.next_out = tif->tif_rawdata;
  1020. sp->stream.avail_out = tif->tif_rawdatasize;
  1021. }
  1022. } while (sp->stream.avail_in > 0);
  1023. return (1);
  1024. }
  1025. /*
  1026. * Finish off an encoded strip by flushing the last
  1027. * string and tacking on an End Of Information code.
  1028. */
  1029. static int
  1030. PixarLogPostEncode(TIFF* tif)
  1031. {
  1032. PixarLogState *sp = EncoderState(tif);
  1033. static const char module[] = "PixarLogPostEncode";
  1034. int state;
  1035. sp->stream.avail_in = 0;
  1036. do {
  1037. state = deflate(&sp->stream, Z_FINISH);
  1038. switch (state) {
  1039. case Z_STREAM_END:
  1040. case Z_OK:
  1041. if (sp->stream.avail_out != (uint32)tif->tif_rawdatasize) {
  1042. tif->tif_rawcc =
  1043. tif->tif_rawdatasize - sp->stream.avail_out;
  1044. TIFFFlushData1(tif);
  1045. sp->stream.next_out = tif->tif_rawdata;
  1046. sp->stream.avail_out = tif->tif_rawdatasize;
  1047. }
  1048. break;
  1049. default:
  1050. TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
  1051. tif->tif_name, sp->stream.msg);
  1052. return (0);
  1053. }
  1054. } while (state != Z_STREAM_END);
  1055. return (1);
  1056. }
  1057. static void
  1058. PixarLogClose(TIFF* tif)
  1059. {
  1060. TIFFDirectory *td = &tif->tif_dir;
  1061. /* In a really sneaky maneuver, on close, we covertly modify both
  1062. * bitspersample and sampleformat in the directory to indicate
  1063. * 8-bit linear. This way, the decode "just works" even for
  1064. * readers that don't know about PixarLog, or how to set
  1065. * the PIXARLOGDATFMT pseudo-tag.
  1066. */
  1067. td->td_bitspersample = 8;
  1068. td->td_sampleformat = SAMPLEFORMAT_UINT;
  1069. }
  1070. static void
  1071. PixarLogCleanup(TIFF* tif)
  1072. {
  1073. PixarLogState* sp = (PixarLogState*) tif->tif_data;
  1074. assert(sp != 0);
  1075. (void)TIFFPredictorCleanup(tif);
  1076. tif->tif_tagmethods.vgetfield = sp->vgetparent;
  1077. tif->tif_tagmethods.vsetfield = sp->vsetparent;
  1078. if (sp->FromLT2) _TIFFfree(sp->FromLT2);
  1079. if (sp->From14) _TIFFfree(sp->From14);
  1080. if (sp->From8) _TIFFfree(sp->From8);
  1081. if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
  1082. if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
  1083. if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
  1084. if (sp->state&PLSTATE_INIT) {
  1085. if (tif->tif_mode == O_RDONLY)
  1086. inflateEnd(&sp->stream);
  1087. else
  1088. deflateEnd(&sp->stream);
  1089. }
  1090. if (sp->tbuf)
  1091. _TIFFfree(sp->tbuf);
  1092. _TIFFfree(sp);
  1093. tif->tif_data = NULL;
  1094. _TIFFSetDefaultCompressionState(tif);
  1095. }
  1096. static int
  1097. PixarLogVSetField(TIFF* tif, ttag_t tag, va_list ap)
  1098. {
  1099. PixarLogState *sp = (PixarLogState *)tif->tif_data;
  1100. int result;
  1101. static const char module[] = "PixarLogVSetField";
  1102. switch (tag) {
  1103. case TIFFTAG_PIXARLOGQUALITY:
  1104. sp->quality = va_arg(ap, int);
  1105. if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
  1106. if (deflateParams(&sp->stream,
  1107. sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
  1108. TIFFErrorExt(tif->tif_clientdata, module, "%s: zlib error: %s",
  1109. tif->tif_name, sp->stream.msg);
  1110. return (0);
  1111. }
  1112. }
  1113. return (1);
  1114. case TIFFTAG_PIXARLOGDATAFMT:
  1115. sp->user_datafmt = va_arg(ap, int);
  1116. /* Tweak the TIFF header so that the rest of libtiff knows what
  1117. * size of data will be passed between app and library, and
  1118. * assume that the app knows what it is doing and is not
  1119. * confused by these header manipulations...
  1120. */
  1121. switch (sp->user_datafmt) {
  1122. case PIXARLOGDATAFMT_8BIT:
  1123. case PIXARLOGDATAFMT_8BITABGR:
  1124. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
  1125. TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
  1126. break;
  1127. case PIXARLOGDATAFMT_11BITLOG:
  1128. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
  1129. TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
  1130. break;
  1131. case PIXARLOGDATAFMT_12BITPICIO:
  1132. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
  1133. TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
  1134. break;
  1135. case PIXARLOGDATAFMT_16BIT:
  1136. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
  1137. TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
  1138. break;
  1139. case PIXARLOGDATAFMT_FLOAT:
  1140. TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
  1141. TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
  1142. break;
  1143. }
  1144. /*
  1145. * Must recalculate sizes should bits/sample change.
  1146. */
  1147. tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tsize_t) -1;
  1148. tif->tif_scanlinesize = TIFFScanlineSize(tif);
  1149. result = 1; /* NB: pseudo tag */
  1150. break;
  1151. default:
  1152. result = (*sp->vsetparent)(tif, tag, ap);
  1153. }
  1154. return (result);
  1155. }
  1156. static int
  1157. PixarLogVGetField(TIFF* tif, ttag_t tag, va_list ap)
  1158. {
  1159. PixarLogState *sp = (PixarLogState *)tif->tif_data;
  1160. switch (tag) {
  1161. case TIFFTAG_PIXARLOGQUALITY:
  1162. *va_arg(ap, int*) = sp->quality;
  1163. break;
  1164. case TIFFTAG_PIXARLOGDATAFMT:
  1165. *va_arg(ap, int*) = sp->user_datafmt;
  1166. break;
  1167. default:
  1168. return (*sp->vgetparent)(tif, tag, ap);
  1169. }
  1170. return (1);
  1171. }
  1172. static const TIFFFieldInfo pixarlogFieldInfo[] = {
  1173. {TIFFTAG_PIXARLOGDATAFMT,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""},
  1174. {TIFFTAG_PIXARLOGQUALITY,0,0,TIFF_ANY, FIELD_PSEUDO,FALSE,FALSE,""}
  1175. };
  1176. int
  1177. TIFFInitPixarLog(TIFF* tif, int scheme)
  1178. {
  1179. static const char module[] = "TIFFInitPixarLog";
  1180. PixarLogState* sp;
  1181. assert(scheme == COMPRESSION_PIXARLOG);
  1182. /*
  1183. * Merge codec-specific tag information.
  1184. */
  1185. if (!_TIFFMergeFieldInfo(tif, pixarlogFieldInfo,
  1186. TIFFArrayCount(pixarlogFieldInfo))) {
  1187. TIFFErrorExt(tif->tif_clientdata, module,
  1188. "Merging PixarLog codec-specific tags failed");
  1189. return 0;
  1190. }
  1191. /*
  1192. * Allocate state block so tag methods have storage to record values.
  1193. */
  1194. tif->tif_data = (tidata_t) _TIFFmalloc(sizeof (PixarLogState));
  1195. if (tif->tif_data == NULL)
  1196. goto bad;
  1197. sp = (PixarLogState*) tif->tif_data;
  1198. _TIFFmemset(sp, 0, sizeof (*sp));
  1199. sp->stream.data_type = Z_BINARY;
  1200. sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
  1201. /*
  1202. * Install codec methods.
  1203. */
  1204. tif->tif_setupdecode = PixarLogSetupDecode;
  1205. tif->tif_predecode = PixarLogPreDecode;
  1206. tif->tif_decoderow = PixarLogDecode;
  1207. tif->tif_decodestrip = PixarLogDecode;
  1208. tif->tif_decodetile = PixarLogDecode;
  1209. tif->tif_setupencode = PixarLogSetupEncode;
  1210. tif->tif_preencode = PixarLogPreEncode;
  1211. tif->tif_postencode = PixarLogPostEncode;
  1212. tif->tif_encoderow = PixarLogEncode;
  1213. tif->tif_encodestrip = PixarLogEncode;
  1214. tif->tif_encodetile = PixarLogEncode;
  1215. tif->tif_close = PixarLogClose;
  1216. tif->tif_cleanup = PixarLogCleanup;
  1217. /* Override SetField so we can handle our private pseudo-tag */
  1218. sp->vgetparent = tif->tif_tagmethods.vgetfield;
  1219. tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */
  1220. sp->vsetparent = tif->tif_tagmethods.vsetfield;
  1221. tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */
  1222. /* Default values for codec-specific fields */
  1223. sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
  1224. sp->state = 0;
  1225. /* we don't wish to use the predictor,
  1226. * the default is none, which predictor value 1
  1227. */
  1228. (void) TIFFPredictorInit(tif);
  1229. /*
  1230. * build the companding tables
  1231. */
  1232. PixarLogMakeTables(sp);
  1233. return (1);
  1234. bad:
  1235. TIFFErrorExt(tif->tif_clientdata, module,
  1236. "No space for PixarLog state block");
  1237. return (0);
  1238. }
  1239. #endif /* PIXARLOG_SUPPORT */
  1240. /* vim: set ts=8 sts=8 sw=8 noet: */
  1241. /*
  1242. * Local Variables:
  1243. * mode: c
  1244. * c-basic-offset: 8
  1245. * fill-column: 78
  1246. * End:
  1247. */