00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "plstdpch.h"
00014
00015 #include <stdarg.h>
00016 #include "pltiffenc.h"
00017 #include "plbitmap.h"
00018 #include "plexcept.h"
00019 extern "C"
00020 {
00021 #include "tiffio.h"
00022 #include "tif_msrc.h"
00023 }
00024
00025
00027
00028
00029
00030 PLTIFFEncoder::PLTIFFEncoder()
00031 : PLPicEncoder()
00032 {
00033 m_Compression = COMPRESSION_PACKBITS;
00034 }
00035
00036
00037
00038 PLTIFFEncoder::~PLTIFFEncoder()
00039 {}
00040
00041 void PLTIFFEncoder::SetCompression (PLWORD Compression)
00042 {
00043 m_Compression = Compression;
00044 }
00045
00046
00047 void PLTIFFEncoder::DoEncode (PLBmp * pBmp, PLDataSink* pDataSnk)
00048 {
00049 TIFF* tif = TIFFOpenMem (pDataSnk->m_pStartData,
00050 pDataSnk->m_nMaxFileSize,
00051 &(pDataSnk->m_nCurPos));
00052 PLASSERT( tif );
00053
00054
00055
00056
00057
00058
00059 SetBaseTags( tif, pBmp );
00060
00061 DoTiffEncode( pBmp, tif );
00062
00063 TIFFClose( tif );
00064 }
00065
00066
00067 void PLTIFFEncoder::DoTiffEncode (PLBmp* pBmp, TIFF* tif)
00068 {
00069 int k;
00070 uint32 l, c, image_length, image_width;
00071
00072 PLBYTE **pla = pBmp->GetLineArray();
00073 PLASSERT( pla );
00074
00075 image_length = (uint32) pBmp->GetHeight();
00076 image_width = (uint32) pBmp->GetWidth();
00077 switch (pBmp->GetBitsPerPixel())
00078 {
00079 case 8:
00080 {
00081
00082 uint16 red[256];
00083 uint16 green[256];
00084 uint16 blue[256];
00085
00086 PLPixel32 * pPal = pBmp->GetPalette();
00087 PLASSERT( pPal );
00088 for (int i = 0; i < pBmp->GetNumColors(); i++, pPal++)
00089 {
00090 red[i] = pPal->GetR ();
00091 green[i] = pPal->GetG ();
00092 blue[i] = pPal->GetB ();
00093 }
00094 SetField( tif, TIFFTAG_COLORMAP, red, green, blue );
00095 }
00096
00097
00098 case 1:
00099 for (l = 0; l < image_length; l++)
00100 k = TIFFWriteScanline( tif, pla[l], l, 0 );
00101 break;
00102
00103 case 32:
00104 {
00105
00106 PLBYTE* pBuf = new PLBYTE[3*image_width];
00107 for (l = 0; l < image_length; l++)
00108 {
00109 for (c = 0; c < image_width; c++)
00110 {
00111 pBuf[c*3 + 0] = pla[l][c*sizeof(PLPixel32) + PL_RGBA_RED];
00112 pBuf[c*3 + 1] = pla[l][c*sizeof(PLPixel32) + PL_RGBA_GREEN];
00113 pBuf[c*3 + 2] = pla[l][c*sizeof(PLPixel32) + PL_RGBA_BLUE];
00114 }
00115 k = TIFFWriteScanline( tif, pBuf, l, 0 );
00116 }
00117 delete [] pBuf;
00118 }
00119 break;
00120
00121 default:
00122 PLASSERT(false);
00123 }
00124
00125 }
00126
00127
00128
00129
00130
00131 int PLTIFFEncoder::SetBaseTags (TIFF* tif, PLBmp* pBmp)
00132 {
00133 PLASSERT( tif && pBmp );
00134
00135 uint16 ui16 = 0;
00136 uint32 ui32 = 0;
00137
00138 ui32 = pBmp->GetWidth();
00139 SetField( tif, TIFFTAG_IMAGEWIDTH, ui32 );
00140 ui32 = pBmp->GetHeight();
00141 SetField( tif, TIFFTAG_IMAGELENGTH, ui32 );
00142
00143
00144 ui16 = pBmp->GetBitsPerPixel();
00145 if (ui16 > 8) ui16 = 8;
00146 SetField( tif, TIFFTAG_BITSPERSAMPLE, ui16 );
00147 ui16 = pBmp->GetBitsPerPixel();
00148 ui16 = ui16 <= 8 ? 1 : 3;
00149 SetField( tif, TIFFTAG_SAMPLESPERPIXEL, ui16 );
00150
00151
00152 ui16 = m_Compression;
00153 SetField( tif, TIFFTAG_COMPRESSION, ui16 );
00154
00155 ui16 = PLANARCONFIG_CONTIG;
00156 SetField( tif, TIFFTAG_PLANARCONFIG, ui16 );
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 float nRes = float(pBmp->GetResolution().x);
00174 SetField(tif,TIFFTAG_XRESOLUTION,nRes);
00175 nRes = float(pBmp->GetResolution().y);
00176 SetField(tif,TIFFTAG_YRESOLUTION,nRes);
00177 SetField (tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
00178
00179 switch (pBmp->GetBitsPerPixel())
00180 {
00181 case 1:
00182 {
00183
00184 PLBYTE* p = (PLBYTE*) pBmp->GetPalette();
00185 ui16 = p[PL_RGBA_RED] < p[PL_RGBA_RED + sizeof(PLPixel32)] &&
00186 p[PL_RGBA_GREEN] < p[PL_RGBA_GREEN + sizeof(PLPixel32)] &&
00187 p[PL_RGBA_BLUE] < p[PL_RGBA_BLUE + sizeof(PLPixel32)] ?
00188 PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_MINISWHITE;
00189 SetField( tif, TIFFTAG_PHOTOMETRIC, ui16 );
00190 }
00191 break;
00192
00193 case 8:
00194 ui16 = PHOTOMETRIC_PALETTE;
00195 SetField( tif, TIFFTAG_PHOTOMETRIC, ui16 );
00196 break;
00197
00198 case 32:
00199 ui16 = PHOTOMETRIC_RGB;
00200 SetField( tif, TIFFTAG_PHOTOMETRIC, ui16 );
00201 break;
00202
00203 default:
00204 PLASSERT(false);
00205 }
00206
00207 return 1;
00208 }
00209
00210
00211
00212
00213 int PLTIFFEncoder::SetField( TIFF* tif, int tag_id, ... )
00214 {
00215 int retv;
00216 va_list marker;
00217
00218 va_start( marker, tag_id );
00219 retv = TIFFVSetField( tif, tag_id, marker );
00220 va_end( marker );
00221
00222 return retv;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287