1 /* 2 * Copyright (c) 1988-1997 Sam Leffler 3 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and 6 * its documentation for any purpose is hereby granted without fee, provided 7 * that (i) the above copyright notices and this permission notice appear in 8 * all copies of the software and related documentation, and (ii) the names of 9 * Sam Leffler and Silicon Graphics may not be used in any advertising or 10 * publicity relating to the software without the specific, prior written 11 * permission of Sam Leffler and Silicon Graphics. 12 * 13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25 /* 26 * TIFF Library. 27 * 28 * JBIG Compression Algorithm Support. 29 * Contributed by Lee Howard <faxguy@deanox.com> 30 * 31 */ 32 33 #include "tiffiop.h" 34 35 #ifdef JBIG_SUPPORT 36 #include "jbig.h" 37 38 static int JBIGSetupDecode(TIFF* tif) 39 { 40 if (TIFFNumberOfStrips(tif) != 1) 41 { 42 TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in decoder"); 43 return 0; 44 } 45 46 return 1; 47 } 48 49 static int JBIGDecode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) 50 { 51 struct jbg_dec_state decoder; 52 int decodeStatus = 0; 53 unsigned char* pImage = NULL; 54 unsigned long decodedSize; 55 (void) s; 56 57 if (isFillOrder(tif, tif->tif_dir.td_fillorder)) 58 { 59 TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); 60 } 61 62 jbg_dec_init(&decoder); 63 64 #if defined(HAVE_JBG_NEWLEN) 65 jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); 66 /* 67 * I do not check the return status of jbg_newlen because even if this 68 * function fails it does not necessarily mean that decoding the image 69 * will fail. It is generally only needed for received fax images 70 * that do not contain the actual length of the image in the BIE 71 * header. I do not log when an error occurs because that will cause 72 * problems when converting JBIG encoded TIFF's to 73 * PostScript. As long as the actual image length is contained in the 74 * BIE header jbg_dec_in should succeed. 75 */ 76 #endif /* HAVE_JBG_NEWLEN */ 77 78 decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, 79 (size_t)tif->tif_rawcc, NULL); 80 if (JBG_EOK != decodeStatus) 81 { 82 /* 83 * XXX: JBG_EN constant was defined in pre-2.0 releases of the 84 * JBIG-KIT. Since the 2.0 the error reporting functions were 85 * changed. We will handle both cases here. 86 */ 87 TIFFErrorExt(tif->tif_clientdata, 88 "JBIG", "Error (%d) decoding: %s", 89 decodeStatus, 90 #if defined(JBG_EN) 91 jbg_strerror(decodeStatus, JBG_EN) 92 #else 93 jbg_strerror(decodeStatus) 94 #endif 95 ); 96 jbg_dec_free(&decoder); 97 return 0; 98 } 99 100 decodedSize = jbg_dec_getsize(&decoder); 101 if( (tmsize_t)decodedSize < size ) 102 { 103 TIFFWarningExt(tif->tif_clientdata, "JBIG", 104 "Only decoded %lu bytes, whereas %lu requested", 105 decodedSize, (unsigned long)size); 106 } 107 else if( (tmsize_t)decodedSize > size ) 108 { 109 TIFFErrorExt(tif->tif_clientdata, "JBIG", 110 "Decoded %lu bytes, whereas %lu were requested", 111 decodedSize, (unsigned long)size); 112 jbg_dec_free(&decoder); 113 return 0; 114 } 115 pImage = jbg_dec_getimage(&decoder, 0); 116 _TIFFmemcpy(buffer, pImage, decodedSize); 117 jbg_dec_free(&decoder); 118 119 tif->tif_rawcp += tif->tif_rawcc; 120 tif->tif_rawcc = 0; 121 122 return 1; 123 } 124 125 static int JBIGSetupEncode(TIFF* tif) 126 { 127 if (TIFFNumberOfStrips(tif) != 1) 128 { 129 TIFFErrorExt(tif->tif_clientdata, "JBIG", "Multistrip images not supported in encoder"); 130 return 0; 131 } 132 133 return 1; 134 } 135 136 static int JBIGCopyEncodedData(TIFF* tif, unsigned char* pp, size_t cc, uint16 s) 137 { 138 (void) s; 139 while (cc > 0) 140 { 141 tmsize_t n = (tmsize_t)cc; 142 143 if (tif->tif_rawcc + n > tif->tif_rawdatasize) 144 { 145 n = tif->tif_rawdatasize - tif->tif_rawcc; 146 } 147 148 assert(n > 0); 149 _TIFFmemcpy(tif->tif_rawcp, pp, n); 150 tif->tif_rawcp += n; 151 tif->tif_rawcc += n; 152 pp += n; 153 cc -= (size_t)n; 154 if (tif->tif_rawcc >= tif->tif_rawdatasize && 155 !TIFFFlushData1(tif)) 156 { 157 return (-1); 158 } 159 } 160 161 return (1); 162 } 163 164 static void JBIGOutputBie(unsigned char* buffer, size_t len, void* userData) 165 { 166 TIFF* tif = (TIFF*)userData; 167 168 if (isFillOrder(tif, tif->tif_dir.td_fillorder)) 169 { 170 TIFFReverseBits(buffer, (tmsize_t)len); 171 } 172 173 JBIGCopyEncodedData(tif, buffer, len, 0); 174 } 175 176 static int JBIGEncode(TIFF* tif, uint8* buffer, tmsize_t size, uint16 s) 177 { 178 TIFFDirectory* dir = &tif->tif_dir; 179 struct jbg_enc_state encoder; 180 181 (void) size, (void) s; 182 183 jbg_enc_init(&encoder, 184 dir->td_imagewidth, 185 dir->td_imagelength, 186 1, 187 &buffer, 188 JBIGOutputBie, 189 tif); 190 /* 191 * jbg_enc_out does the "real" encoding. As data is encoded, 192 * JBIGOutputBie is called, which writes the data to the directory. 193 */ 194 jbg_enc_out(&encoder); 195 jbg_enc_free(&encoder); 196 197 return 1; 198 } 199 200 int TIFFInitJBIG(TIFF* tif, int scheme) 201 { 202 assert(scheme == COMPRESSION_JBIG); 203 204 /* 205 * These flags are set so the JBIG Codec can control when to reverse 206 * bits and when not to and to allow the jbig decoder and bit reverser 207 * to write to memory when necessary. 208 */ 209 tif->tif_flags |= TIFF_NOBITREV; 210 tif->tif_flags &= ~TIFF_MAPPED; 211 212 /* Setup the function pointers for encode, decode, and cleanup. */ 213 tif->tif_setupdecode = JBIGSetupDecode; 214 tif->tif_decodestrip = JBIGDecode; 215 216 tif->tif_setupencode = JBIGSetupEncode; 217 tif->tif_encodestrip = JBIGEncode; 218 219 return 1; 220 } 221 222 #endif /* JBIG_SUPPORT */ 223 224 /* vim: set ts=8 sts=8 sw=8 noet: */ 225 226 /* 227 * Local Variables: 228 * mode: c 229 * c-basic-offset: 8 230 * fill-column: 78 231 * End: 232 */ 233