WIP: insert elements from V2 framework into the trunk (add missing files)
[openjpeg.git] / thirdparty / libtiff / tif_jbig.c
1 /* $Id: tif_jbig.c,v 1.2.2.3 2010-06-08 18:50:42 bfriesen Exp $ */
2
3 /*
4  * Copyright (c) 1988-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and 
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
18  * 
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
24  * OF THIS SOFTWARE.
25  */
26
27 /*
28  * TIFF Library.
29  *
30  * JBIG Compression Algorithm Support.
31  * Contributed by Lee Howard <faxguy@deanox.com>
32  * 
33  */
34
35 #include "tiffiop.h"
36
37 #ifdef JBIG_SUPPORT
38 #include "jbig.h"
39
40 typedef struct
41 {
42         uint32  recvparams;     /* encoded Class 2 session params             */
43         char*   subaddress;     /* subaddress string                          */
44         uint32  recvtime;       /* time spend receiving in seconds            */
45         char*   faxdcs;         /* encoded fax parameters (DCS, Table 2/T.30) */
46
47         TIFFVGetMethod vgetparent;
48         TIFFVSetMethod vsetparent;
49 } JBIGState;
50
51 #define GetJBIGState(tif) ((JBIGState*)(tif)->tif_data)
52
53 #define FIELD_RECVPARAMS        (FIELD_CODEC+0)
54 #define FIELD_SUBADDRESS        (FIELD_CODEC+1)
55 #define FIELD_RECVTIME          (FIELD_CODEC+2)
56 #define FIELD_FAXDCS            (FIELD_CODEC+3)
57
58 static const TIFFFieldInfo jbigFieldInfo[] = 
59 {
60         {TIFFTAG_FAXRECVPARAMS,  1,  1, TIFF_LONG,  FIELD_RECVPARAMS, TRUE, FALSE, "FaxRecvParams"},
61         {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, FIELD_SUBADDRESS, TRUE, FALSE, "FaxSubAddress"},
62         {TIFFTAG_FAXRECVTIME,    1,  1, TIFF_LONG,  FIELD_RECVTIME,   TRUE, FALSE, "FaxRecvTime"},
63         {TIFFTAG_FAXDCS,        -1, -1, TIFF_ASCII, FIELD_FAXDCS,     TRUE, FALSE, "FaxDcs"},
64 };
65
66 static int JBIGSetupDecode(TIFF* tif)
67 {
68         if (TIFFNumberOfStrips(tif) != 1)
69         {
70                 TIFFError("JBIG", "Multistrip images not supported in decoder");
71                 return 0;
72         }
73
74         return 1;
75 }
76
77 static int JBIGDecode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s)
78 {
79         struct jbg_dec_state decoder;
80         int decodeStatus = 0;
81         unsigned char* pImage = NULL;
82         (void) size, (void) s;
83
84         if (isFillOrder(tif, tif->tif_dir.td_fillorder))
85         {
86                 TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdatasize);
87         }
88
89         jbg_dec_init(&decoder);
90
91 #if defined(HAVE_JBG_NEWLEN)
92         jbg_newlen(tif->tif_rawdata, tif->tif_rawdatasize);
93         /*
94          * I do not check the return status of jbg_newlen because even if this
95          * function fails it does not necessarily mean that decoding the image
96          * will fail.  It is generally only needed for received fax images
97          * that do not contain the actual length of the image in the BIE
98          * header.  I do not log when an error occurs because that will cause
99          * problems when converting JBIG encoded TIFF's to 
100          * PostScript.  As long as the actual image length is contained in the
101          * BIE header jbg_dec_in should succeed.
102          */
103 #endif /* HAVE_JBG_NEWLEN */
104
105         decodeStatus = jbg_dec_in(&decoder, tif->tif_rawdata,
106                                   tif->tif_rawdatasize, NULL);
107         if (JBG_EOK != decodeStatus)
108         {
109                 /*
110                  * XXX: JBG_EN constant was defined in pre-2.0 releases of the
111                  * JBIG-KIT. Since the 2.0 the error reporting functions were
112                  * changed. We will handle both cases here.
113                  */
114                 TIFFError("JBIG", "Error (%d) decoding: %s", decodeStatus,
115 #if defined(JBG_EN)
116                           jbg_strerror(decodeStatus, JBG_EN)
117 #else
118                           jbg_strerror(decodeStatus)
119 #endif
120                          );
121                 return 0;
122         }
123         
124         pImage = jbg_dec_getimage(&decoder, 0);
125         _TIFFmemcpy(buffer, pImage, jbg_dec_getsize(&decoder));
126         jbg_dec_free(&decoder);
127         return 1;
128 }
129
130 static int JBIGSetupEncode(TIFF* tif)
131 {
132         if (TIFFNumberOfStrips(tif) != 1)
133         {
134                 TIFFError("JBIG", "Multistrip images not supported in encoder");
135                 return 0;
136         }
137
138         return 1;
139 }
140
141 static int JBIGCopyEncodedData(TIFF* tif, tidata_t pp, tsize_t cc, tsample_t s)
142 {
143         (void) s;
144         while (cc > 0) 
145         {
146                 tsize_t n = cc;
147
148                 if (tif->tif_rawcc + n > tif->tif_rawdatasize)
149                 {
150                         n = tif->tif_rawdatasize - tif->tif_rawcc;
151                 }
152
153                 assert(n > 0);
154                 _TIFFmemcpy(tif->tif_rawcp, pp, n);
155                 tif->tif_rawcp += n;
156                 tif->tif_rawcc += n;
157                 pp += n;
158                 cc -= n;
159                 if (tif->tif_rawcc >= tif->tif_rawdatasize &&
160                     !TIFFFlushData1(tif))
161                 {
162                         return (-1);
163                 }
164         }
165
166         return (1);
167 }
168
169 static void JBIGOutputBie(unsigned char* buffer, size_t len, void *userData)
170 {
171         TIFF* tif = (TIFF*)userData;
172
173         if (isFillOrder(tif, tif->tif_dir.td_fillorder))
174         {
175                 TIFFReverseBits(buffer, len);
176         }
177
178         JBIGCopyEncodedData(tif, buffer, len, 0);
179 }
180
181 static int JBIGEncode(TIFF* tif, tidata_t buffer, tsize_t size, tsample_t s)
182 {
183         TIFFDirectory* dir = &tif->tif_dir;
184         struct jbg_enc_state encoder;
185
186         (void) size, (void) s;
187
188         jbg_enc_init(&encoder, 
189                      dir->td_imagewidth, 
190                      dir->td_imagelength, 
191                      1, 
192                      &buffer,
193                      JBIGOutputBie,
194                      tif);
195         /* 
196          * jbg_enc_out does the "real" encoding.  As data is encoded,
197          * JBIGOutputBie is called, which writes the data to the directory.
198          */
199         jbg_enc_out(&encoder);
200         jbg_enc_free(&encoder);
201
202         return 1;
203 }
204
205 static void JBIGCleanup(TIFF* tif)
206 {
207         JBIGState *sp = GetJBIGState(tif);
208
209         assert(sp != 0);
210
211         tif->tif_tagmethods.vgetfield = sp->vgetparent;
212         tif->tif_tagmethods.vsetfield = sp->vsetparent;
213
214         _TIFFfree(tif->tif_data);
215         tif->tif_data = NULL;
216
217         _TIFFSetDefaultCompressionState(tif);
218 }
219
220 static void JBIGPrintDir(TIFF* tif, FILE* fd, long flags)
221 {
222         JBIGState* codec = GetJBIGState(tif);
223         (void)flags;
224
225         if (TIFFFieldSet(tif, FIELD_RECVPARAMS))
226         {
227                 fprintf(fd, 
228                         "  Fax Receive Parameters: %08lx\n",
229                         (unsigned long)codec->recvparams);
230         }
231
232         if (TIFFFieldSet(tif, FIELD_SUBADDRESS))
233         {
234                 fprintf(fd, 
235                         "  Fax SubAddress: %s\n", 
236                         codec->subaddress);
237         }
238
239         if (TIFFFieldSet(tif, FIELD_RECVTIME))
240         {
241                 fprintf(fd, 
242                         "  Fax Receive Time: %lu secs\n",
243                         (unsigned long)codec->recvtime);
244         }
245
246         if (TIFFFieldSet(tif, FIELD_FAXDCS))
247         {
248                 fprintf(fd, 
249                         "  Fax DCS: %s\n", 
250                         codec->faxdcs);
251         }
252 }
253
254 static int JBIGVGetField(TIFF* tif, ttag_t tag, va_list ap)
255 {
256         JBIGState* codec = GetJBIGState(tif);
257
258         switch (tag)
259         {
260                 case TIFFTAG_FAXRECVPARAMS:
261                         *va_arg(ap, uint32*) = codec->recvparams;
262                         break;
263                 
264                 case TIFFTAG_FAXSUBADDRESS:
265                         *va_arg(ap, char**) = codec->subaddress;
266                         break;
267
268                 case TIFFTAG_FAXRECVTIME:
269                         *va_arg(ap, uint32*) = codec->recvtime;
270                         break;
271
272                 case TIFFTAG_FAXDCS:
273                         *va_arg(ap, char**) = codec->faxdcs;
274                         break;
275
276                 default:
277                         return (*codec->vgetparent)(tif, tag, ap);
278         }
279
280         return 1;
281 }
282
283 static int JBIGVSetField(TIFF* tif, ttag_t tag, va_list ap)
284 {
285         JBIGState* codec = GetJBIGState(tif);
286
287         switch (tag)
288         {
289                 case TIFFTAG_FAXRECVPARAMS:
290                         codec->recvparams = va_arg(ap, uint32);
291                         break;
292
293                 case TIFFTAG_FAXSUBADDRESS:
294                         _TIFFsetString(&codec->subaddress, va_arg(ap, char*));
295                         break;
296
297                 case TIFFTAG_FAXRECVTIME:
298                         codec->recvtime = va_arg(ap, uint32);
299                         break;
300
301                 case TIFFTAG_FAXDCS:
302                         _TIFFsetString(&codec->faxdcs, va_arg(ap, char*));
303                         break;
304
305                 default:
306                         return (*codec->vsetparent)(tif, tag, ap);
307         }
308
309         TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit);
310         tif->tif_flags |= TIFF_DIRTYDIRECT;
311         return 1;
312 }
313
314 int TIFFInitJBIG(TIFF* tif, int scheme)
315 {
316         JBIGState* codec = NULL;
317
318         assert(scheme == COMPRESSION_JBIG);
319
320         /*
321          * Merge codec-specific tag information.
322          */
323         if (!_TIFFMergeFieldInfo(tif, jbigFieldInfo,
324                                  TIFFArrayCount(jbigFieldInfo))) {
325                 TIFFErrorExt(tif->tif_clientdata, "TIFFInitJBIG",
326                              "Merging JBIG codec-specific tags failed");
327                 return 0;
328         }
329
330         /* Allocate memory for the JBIGState structure.*/
331         tif->tif_data = (tdata_t)_TIFFmalloc(sizeof(JBIGState));
332         if (tif->tif_data == NULL)
333         {
334                 TIFFError("TIFFInitJBIG", "Not enough memory for JBIGState");
335                 return 0;
336         }
337         _TIFFmemset(tif->tif_data, 0, sizeof(JBIGState));
338         codec = GetJBIGState(tif);
339
340         /* Initialize codec private fields */
341         codec->recvparams = 0;
342         codec->subaddress = NULL;
343         codec->faxdcs = NULL;
344         codec->recvtime = 0;
345
346         /* 
347          * Override parent get/set field methods.
348          */
349         codec->vgetparent = tif->tif_tagmethods.vgetfield;
350         codec->vsetparent = tif->tif_tagmethods.vsetfield;
351         tif->tif_tagmethods.vgetfield = JBIGVGetField;
352         tif->tif_tagmethods.vsetfield = JBIGVSetField;
353         tif->tif_tagmethods.printdir = JBIGPrintDir;
354
355         /*
356          * These flags are set so the JBIG Codec can control when to reverse
357          * bits and when not to and to allow the jbig decoder and bit reverser
358          * to write to memory when necessary.
359          */
360         tif->tif_flags |= TIFF_NOBITREV;
361         tif->tif_flags &= ~TIFF_MAPPED;
362
363         /* Setup the function pointers for encode, decode, and cleanup. */
364         tif->tif_setupdecode = JBIGSetupDecode;
365         tif->tif_decodestrip = JBIGDecode;
366
367         tif->tif_setupencode = JBIGSetupEncode;
368         tif->tif_encodestrip = JBIGEncode;
369         
370         tif->tif_cleanup = JBIGCleanup;
371
372         return 1;
373 }
374
375 #endif /* JBIG_SUPPORT */
376
377 /* vim: set ts=8 sts=8 sw=8 noet: */
378
379 /*
380  * Local Variables:
381  * mode: c
382  * c-basic-offset: 8
383  * fill-column: 78
384  * End:
385  */