Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

pltiffenc.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: pltiffenc.cpp,v 1.1 2004/05/21 21:02:53 maxx Exp $
00005 |
00006 |      TIFF file encoder. Uses LIBTIFF to do the actual conversion.
00007 |
00008 |      Copyright (c) 1996-2002 Ulrich von Zadow
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"   // for the tags definitions
00022 #include "tif_msrc.h"
00023 }
00024 
00025 
00027 // Class functions
00028 
00029 // Creates an encoder
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   if (!tif)
00055   raiseError (PL_ERRWRONG_SIGNATURE, PLTIFFDecoder::m_szLastErr);
00056   */
00057 
00058   // initialize TIFF "directory"
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   // iterate over data
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         // first, save the colormap
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       // fall-through
00097 
00098     case 1:  // TODO: a bit of error checking
00099       for (l = 0; l < image_length; l++)
00100         k = TIFFWriteScanline( tif, pla[l], l, 0 );
00101       break;
00102 
00103     case 32:
00104       {
00105         // TODO: check whether (r,g,b) components come in the correct order here...
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   // we could flush at this point, but TIFFClose will do it anyway
00125 }
00126 
00127 
00128 // According to the characteristics of the given bitmap,
00129 // set the baseline tags
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   // one strip = the whole image
00143   // SetField( tif, TIFFTAG_ROWSPERSTRIP,    ui32 );
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    * The following tags are supposedly mandatory,
00160    * but libtiff seems to have sensible defaults for us
00161    *
00162 
00163   ui32 = 0;
00164   SetField( TIFFTAG_SUBFILETYPE,     ui32 );
00165   ?!?
00166   SetField( TIFFTAG_STRIPOFFSETS,    ui32 );
00167   ?!?
00168   SetField( TIFFTAG_STRIPBYTECOUNT,  ui32 );
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         // look at bi-level palette...
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; // should reflect the successful directory initialisation
00208 }
00209 
00210 
00211 // Set field in directory.
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 );     /* Initialize variable arguments. */
00219   retv = TIFFVSetField( tif, tag_id, marker );
00220   va_end( marker );               /* Reset variable arguments.      */
00221 
00222   return retv;
00223 }
00224 
00225 
00226 /*
00227 /--------------------------------------------------------------------
00228 |
00229 |      $Log: pltiffenc.cpp,v $
00230 |      Revision 1.1  2004/05/21 21:02:53  maxx
00231 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00232 |
00233 |      Revision 1.1  2002/11/13 01:58:22  mspindle
00234 |      *** empty log message ***
00235 |
00236 |      Revision 1.6  2002/01/27 18:20:16  uzadow
00237 |      Updated copyright message; corrected pcx decoder bug.
00238 |
00239 |      Revision 1.5  2001/10/17 13:19:47  uzadow
00240 |      Added support for photoshop tiff alpha channels.
00241 |
00242 |      Revision 1.4  2001/10/16 17:12:26  uzadow
00243 |      Added support for resolution information (Luca Piergentili)
00244 |
00245 |      Revision 1.3  2001/10/06 22:03:26  uzadow
00246 |      Added PL prefix to basic data types.
00247 |
00248 |      Revision 1.2  2001/10/06 20:44:45  uzadow
00249 |      Linux compatibility
00250 |
00251 |      Revision 1.1  2001/09/16 19:03:22  uzadow
00252 |      Added global name prefix PL, changed most filenames.
00253 |
00254 |      Revision 1.14  2001/09/13 20:43:02  uzadow
00255 |      Added tiff compression support.
00256 |
00257 |      Revision 1.13  2001/02/04 14:31:52  uzadow
00258 |      Member initialization list cleanup (Erik Hoffmann).
00259 |
00260 |      Revision 1.12  2000/12/18 22:42:52  uzadow
00261 |      Replaced RGBAPIXEL with PLPixel32.
00262 |
00263 |      Revision 1.11  2000/09/01 14:13:49  Administrator
00264 |      Removed MFC from paintX, added MSCV paintX sample.
00265 |
00266 |      Revision 1.10  2000/01/16 20:43:15  anonymous
00267 |      Removed MFC dependencies
00268 |
00269 |      Revision 1.9  2000/01/10 23:53:00  Ulrich von Zadow
00270 |      Changed formatting & removed tabs.
00271 |
00272 |      Revision 1.8  1999/12/10 01:27:26  Ulrich von Zadow
00273 |      Added assignment operator and copy constructor to
00274 |      bitmap classes.
00275 |
00276 |      Revision 1.7  1999/12/08 15:39:45  Ulrich von Zadow
00277 |      Unix compatibility changes
00278 |
00279 |      Revision 1.6  1999/12/02 17:07:34  Ulrich von Zadow
00280 |      Changes by bdelmee.
00281 |
00282 |      Revision 1.5  1999/10/03 18:50:51  Ulrich von Zadow
00283 |      Added automatic logging of changes.
00284 |
00285 |
00286 \--------------------------------------------------------------------
00287 */

Generated on Wed Dec 15 21:20:30 2004 for vuVolume by  doxygen 1.3.9.1