Hoyt's FORK of DemoIccMAX 2.1.17.hoyt
Documentation for Hoyt's FORK of DemoIccMAX
Loading...
Searching...
No Matches
TiffImg.cpp
Go to the documentation of this file.
1/*
2 File: TiffImg.cpp
3
4 Contains: Implementation of the CTiffImg class.
5
6 Version: V1
7
8 Copyright: (c) see below
9*/
10
11/*
12 * The ICC Software License, Version 0.2
13 *
14 *
15 * Copyright (c) 2003-2010 The International Color Consortium. All rights
16 * reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 *
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 *
30 * 3. In the absence of prior written permission, the names "ICC" and "The
31 * International Color Consortium" must not be used to imply that the
32 * ICC organization endorses or promotes products derived from this
33 * software.
34 *
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
40 * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the The International Color Consortium.
52 *
53 *
54 * Membership in the ICC is encouraged when this software is used for
55 * commercial purposes.
56 *
57 *
58 * For more information on The International Color Consortium, please
59 * see <http://www.color.org/>.
60 *
61 *
62 */
63
64//////////////////////////////////////////////////////////////////////
65// HISTORY:
66//
67// -Initial implementation by Max Derhak 5-15-2003
68//
69//////////////////////////////////////////////////////////////////////
70
71#include <stdio.h>
72#include <stdlib.h>
73#include <string.h>
74#include "TiffImg.h"
75
76
77#ifdef _DEBUG
78#undef THIS_FILE
79static char THIS_FILE[]=__FILE__;
80#define new DEBUG_NEW
81#endif
82
83//////////////////////////////////////////////////////////////////////
84// Construction/Destruction
85//////////////////////////////////////////////////////////////////////
86
88{
89 m_nWidth = 0;
90 m_nHeight = 0;
92 m_nSamples = 0;
94
95 m_hTif = NULL;
96 m_pStripBuf = NULL;
97}
98
100{
101 Close();
102}
103
105{
106 m_nWidth = 0;
107 m_nHeight = 0;
109 m_nSamples = 0;
110 m_nExtraSamples = 0;
111
112 if (m_hTif) {
113 TIFFClose(m_hTif);
114
115 m_hTif = NULL;
116 }
117
118 if (m_pStripBuf) {
119 free(m_pStripBuf);
120 m_pStripBuf = NULL;
121 }
122}
123
124bool CTiffImg::Create(const char *szFname, unsigned int nWidth, unsigned int nHeight,
125 unsigned int nBPS, unsigned int nPhoto, unsigned int nSamples,
126 float fXRes, float fYRes, bool bCompress, bool bSep)
127{
128 Close();
129 m_bRead = false;
130
131 m_nWidth = nWidth;
132 m_nHeight = nHeight;
134 m_nSamples = (icUInt16Number)nSamples;
135 m_nRowsPerStrip = 1;
136 m_fXRes = fXRes;
137 m_fYRes = fYRes;
138 m_nPlanar = bSep ? PLANARCONFIG_SEPARATE : PLANARCONFIG_CONTIG;
139 m_nCompress = bCompress ? COMPRESSION_LZW : COMPRESSION_NONE;
140
141 switch(nPhoto) {
142 case PHOTO_MINISBLACK:
143 if (m_nSamples==3)
144 m_nPhoto = PHOTOMETRIC_RGB;
145 else
146 m_nPhoto = PHOTOMETRIC_MINISBLACK;
147 break;
148
149 case PHOTO_MINISWHITE:
150 if (m_nSamples==4)
151 m_nPhoto = PHOTOMETRIC_SEPARATED;
152 else
153 m_nPhoto = PHOTOMETRIC_MINISWHITE;
154 break;
155
156 case PHOTO_CIELAB:
157 m_nPhoto = PHOTOMETRIC_CIELAB;
158 break;
159
160 case PHOTO_ICCLAB:
161 m_nPhoto = PHOTOMETRIC_ICCLAB;
162 break;
163 }
164
165 m_hTif = TIFFOpen(szFname, "w");
166 if (!m_hTif) {
167 TIFFError(szFname,"Can not open output image");
168 return false;
169 }
170 TIFFSetField(m_hTif, TIFFTAG_IMAGEWIDTH, (uint32) m_nWidth);
171 TIFFSetField(m_hTif, TIFFTAG_IMAGELENGTH, (uint32) m_nHeight);
172 TIFFSetField(m_hTif, TIFFTAG_PHOTOMETRIC, m_nPhoto);
173 TIFFSetField(m_hTif, TIFFTAG_PLANARCONFIG, m_nPlanar);
174 TIFFSetField(m_hTif, TIFFTAG_SAMPLESPERPIXEL, m_nSamples);
175 TIFFSetField(m_hTif, TIFFTAG_BITSPERSAMPLE, m_nBitsPerSample);
176 if (m_nBitsPerSample==32)
177 TIFFSetField(m_hTif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
178 TIFFSetField(m_hTif, TIFFTAG_ROWSPERSTRIP, m_nRowsPerStrip);
179 TIFFSetField(m_hTif, TIFFTAG_COMPRESSION, m_nCompress);
180 TIFFSetField(m_hTif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
181 TIFFSetField(m_hTif, TIFFTAG_XRESOLUTION, fXRes);
182 TIFFSetField(m_hTif, TIFFTAG_YRESOLUTION, fYRes);
183 if (bCompress) {
184 if (m_nBitsPerSample==32) {
185 TIFFSetField(m_hTif, TIFFTAG_PREDICTOR, PREDICTOR_FLOATINGPOINT);
186 }
187 else {
188 TIFFSetField(m_hTif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
189 }
190 }
191
192 m_nCurLine = 0;
193 m_nCurStrip = 0;
194
195 if (bSep && m_nSamples>1) {
197 if (m_nBitsPerSample % 8) {
198 Close();
199 return false;
200 }
202
203 m_nStripSize = (unsigned int)TIFFStripSize(m_hTif);
205
207 Close();
208 return false;
209 }
211
212 m_pStripBuf = (unsigned char*)malloc(m_nStripSize*m_nStripSamples);
213
214 if (!m_pStripBuf) {
215 Close();
216 return false;
217 }
219 }
220 else {
221 m_nBytesPerLine = m_nStripSize = (unsigned int)TIFFStripSize(m_hTif);
222 m_nStripSamples = 1;
223 }
224
225 return true;
226}
227
228bool CTiffImg::Open(const char *szFname)
229{
230 Close();
231 m_bRead = true;
232
233 m_hTif = TIFFOpen(szFname, "r");
234 if (!m_hTif) {
235 TIFFError(szFname,"Can not open input image");
236 return false;
237 }
238 icUInt16Number nPlanar=PLANARCONFIG_CONTIG;
239 icUInt16Number nOrientation=ORIENTATION_TOPLEFT;
240 icUInt16Number nSampleFormat=SAMPLEFORMAT_UINT;
241 icUInt16Number *nSampleInfo=NULL;
242
243 TIFFGetField(m_hTif, TIFFTAG_IMAGEWIDTH, &m_nWidth);
244 TIFFGetField(m_hTif, TIFFTAG_IMAGELENGTH, &m_nHeight);
245 TIFFGetField(m_hTif, TIFFTAG_PHOTOMETRIC, &m_nPhoto);
246 TIFFGetField(m_hTif, TIFFTAG_PLANARCONFIG, &m_nPlanar);
247 TIFFGetField(m_hTif, TIFFTAG_SAMPLESPERPIXEL, &m_nSamples);
248 TIFFGetField(m_hTif, TIFFTAG_EXTRASAMPLES, &m_nExtraSamples, &nSampleInfo);
249 TIFFGetField(m_hTif, TIFFTAG_BITSPERSAMPLE, &m_nBitsPerSample);
250 TIFFGetField(m_hTif, TIFFTAG_SAMPLEFORMAT, &nSampleFormat);
251 TIFFGetField(m_hTif, TIFFTAG_ROWSPERSTRIP, &m_nRowsPerStrip);
252 TIFFGetField(m_hTif, TIFFTAG_ORIENTATION, &nOrientation);
253 TIFFGetField(m_hTif, TIFFTAG_XRESOLUTION, &m_fXRes);
254 TIFFGetField(m_hTif, TIFFTAG_YRESOLUTION, &m_fYRes);
255 TIFFGetField(m_hTif, TIFFTAG_COMPRESSION, &m_nCompress);
256
257 //Validate what we expect to work with
258 if ((m_nBitsPerSample==32 && nSampleFormat!=SAMPLEFORMAT_IEEEFP) ||
259 (m_nBitsPerSample!=32 && nSampleFormat!=SAMPLEFORMAT_UINT) ||
260 nOrientation != ORIENTATION_TOPLEFT) {
261 Close();
262 return false;
263 }
264 m_nCurStrip=(unsigned int)-1;
265 m_nCurLine = 0;
266
267 m_nStripSize = (unsigned int)TIFFStripSize(m_hTif);
268
269 if (m_nSamples>1 && m_nPlanar==PLANARCONFIG_SEPARATE) {
274 //Only support bitspersample that fits on byte boundary
275 if (m_nBitsPerSample%8) {
276 Close();
277 return false;
278 }
280 //Only support separations that evenly fit into strips
282 Close();
283 return false;
284 }
285 }
286 else {
287 m_nStripSamples = 1;
289 }
290
291 m_pStripBuf = (unsigned char*)malloc(m_nStripSize*m_nStripSamples);
292
293 if (!m_pStripBuf) {
294 Close();
295 return false;
296 }
297
298 return true;
299}
300
301
302bool CTiffImg::ReadLine(unsigned char *pBuf)
303{
304 if (!m_bRead)
305 return false;
306
307 unsigned int nStrip = m_nCurLine / m_nRowsPerStrip;
308 unsigned int nRowOffset = m_nCurLine % m_nRowsPerStrip;
309
310 if (nStrip != m_nCurStrip) {
311 m_nCurStrip = nStrip;
312
313 if (m_nStripSamples>1) {
314 unsigned int s;
315 unsigned char *pos = m_pStripBuf;
316 unsigned int nStripOffset = 0;
317 for (s=0; s<m_nStripSamples; s++) {
318 if (TIFFReadEncodedStrip(m_hTif, m_nCurStrip+nStripOffset, pos, m_nStripSize) < 0) {
319 return false;
320 }
321 nStripOffset += m_nStripsPerSample;
323 }
324 }
325 else if (TIFFReadEncodedStrip(m_hTif, m_nCurStrip, m_pStripBuf, m_nStripSize) < 0) {
326 return false;
327 }
328 }
329
330 if (m_nStripSamples>1) { //Sep to contig
331 unsigned char *src, *dst;
332 src = m_pStripBuf+nRowOffset*m_nBytesPerStripLine;
333 dst = pBuf;
334 unsigned int w, s;
335 for (w=0; w<m_nWidth; w++) {
336 unsigned char *pos = src;
337 for (s=0; s<m_nSamples; s++) {
338 memcpy(dst, pos, m_nBytesPerSample);
339 dst += m_nBytesPerSample;
340 pos += m_nStripSize;
341 }
342 src += m_nBytesPerSample;
343 }
344 }
345 else {
346 memcpy(pBuf, m_pStripBuf+nRowOffset*m_nBytesPerLine, m_nBytesPerLine);
347 }
348 m_nCurLine++;
349
350 return true;
351}
352
353bool CTiffImg::WriteLine(unsigned char *pBuf)
354{
355 if (m_bRead)
356 return false;
357
358 if (m_nCurStrip < m_nHeight) { //Contig to Sep
359 if (m_nStripSamples>1) {
360 unsigned char *src, *dst;
361 src = pBuf;
362 dst = m_pStripBuf;
363 unsigned int w, s, offset;
364 for (w=0; w<m_nWidth; w++) {
365 unsigned char *pos = dst;
366 for (s=0; s<m_nSamples; s++) {
367 memcpy(pos, src, m_nBytesPerSample);
368 src += m_nBytesPerSample;
369 pos += m_nStripSize;
370 }
371 dst += m_nBytesPerSample;
372 }
373 offset = 0;
374 src = m_pStripBuf;
375 for (s=0; s<m_nSamples; s++) {
376 if (TIFFWriteEncodedStrip(m_hTif, m_nCurStrip+offset, src, m_nStripSize) < 0)
377 return false;
378 offset += m_nStripsPerSample;
379 src += m_nStripSize;
380 }
381 }
382 else if (TIFFWriteEncodedStrip(m_hTif, m_nCurStrip, pBuf, m_nBytesPerLine) < 0)
383 return false;
384
385 m_nCurStrip++;
386 }
387
388 return true;
389}
390
391unsigned int CTiffImg::GetPhoto()
392{
393 if (m_nPhoto==PHOTOMETRIC_MINISBLACK ||
394 m_nPhoto==PHOTOMETRIC_RGB) {
395 return PHOTO_MINISBLACK;
396 }
397 else if (m_nPhoto==PHOTOMETRIC_MINISWHITE ||
398 m_nPhoto==PHOTOMETRIC_SEPARATED) {
399 return PHOTO_MINISWHITE;
400 }
401 else if (m_nPhoto==PHOTOMETRIC_CIELAB)
402 return PHOTO_CIELAB;
403 else if (m_nPhoto==PHOTOMETRIC_ICCLAB)
404 return PHOTO_ICCLAB;
405 else
406 return PHOTO_MINISWHITE;
407}
408
409
410bool CTiffImg::GetIccProfile(unsigned char *&pProfile, unsigned int &nLen)
411{
412 pProfile = NULL;
413 nLen = 0;
414
415 TIFFGetField(m_hTif, TIFFTAG_ICCPROFILE, &nLen, &pProfile);
416
417 return pProfile!=NULL && nLen>0;
418}
419
420bool CTiffImg::SetIccProfile(unsigned char *pProfile, unsigned int nLen)
421{
422 TIFFSetField(m_hTif, TIFFTAG_ICCPROFILE, nLen, pProfile);
423
424 return true;
425}
#define PHOTO_CIELAB
Definition TiffImg.h:80
#define PHOTO_MINISBLACK
Definition TiffImg.h:78
#define PHOTO_ICCLAB
Definition TiffImg.h:81
#define PHOTO_MINISWHITE
Definition TiffImg.h:79
bool Open(const char *szFname)
Definition TiffImg.cpp:228
float m_fXRes
Definition TiffImg.h:131
void Close()
Definition TiffImg.cpp:104
unsigned int m_nWidth
Definition TiffImg.h:121
unsigned int m_nStripsPerSample
Definition TiffImg.h:138
bool m_bRead
Definition TiffImg.h:119
icUInt16Number m_nExtraSamples
Definition TiffImg.h:127
unsigned int m_nRowsPerStrip
Definition TiffImg.h:135
icUInt16Number m_nCompress
Definition TiffImg.h:129
icUInt16Number m_nPlanar
Definition TiffImg.h:128
unsigned int m_nStripSamples
Definition TiffImg.h:137
icUInt16Number m_nSamples
Definition TiffImg.h:126
virtual ~CTiffImg()
Definition TiffImg.cpp:99
unsigned int GetPhoto()
Definition TiffImg.cpp:391
unsigned int m_nCurStrip
Definition TiffImg.h:144
TIFF * m_hTif
Definition TiffImg.h:118
bool Create(const char *szFname, unsigned int nWidth, unsigned int nHeight, unsigned int nBPS, unsigned int nPhoto, unsigned int nSamples, float fXRes, float fYRes, bool bCompress=true, bool bSep=false)
Definition TiffImg.cpp:124
unsigned int m_nHeight
Definition TiffImg.h:122
float m_fYRes
Definition TiffImg.h:132
icUInt16Number m_nPhoto
Definition TiffImg.h:125
bool WriteLine(unsigned char *pBuf)
Definition TiffImg.cpp:353
unsigned int m_nStripSize
Definition TiffImg.h:136
bool ReadLine(unsigned char *pBuf)
Definition TiffImg.cpp:302
bool SetIccProfile(unsigned char *pProfile, unsigned int nLen)
Definition TiffImg.cpp:420
bool GetIccProfile(unsigned char *&pProfile, unsigned int &nLen)
Definition TiffImg.cpp:410
unsigned int m_nCurLine
Definition TiffImg.h:143
unsigned char * m_pStripBuf
Definition TiffImg.h:141
unsigned int m_nBytesPerLine
Definition TiffImg.h:134
icUInt16Number m_nBitsPerSample
Definition TiffImg.h:123
icUInt16Number m_nBytesPerSample
Definition TiffImg.h:124
unsigned int m_nBytesPerStripLine
Definition TiffImg.h:139
unsigned short icUInt16Number