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

OSGSGIImageFileType.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //-------------------------------
00040 //      Includes                                    
00041 //-------------------------------
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 
00046 #include "OSGConfig.h"
00047 
00048 #include "OSGBaseFunctions.h"
00049 
00050 #include <iostream>
00051 #include <fstream>
00052 
00053 #include <OSGLog.h>
00054 
00055 #include "OSGSGIImageFileType.h"
00056 
00057 #ifdef OSG_SGI_STL
00058 //#include <limits>
00059 #ifndef INT_MAX
00060 #define INT_MAX numeric_limits<int>::max()
00061 #endif
00062 #else
00063 #include <limits.h>
00064 #endif
00065 
00066 OSG_USING_NAMESPACE
00067 
00080 /* the basic reader functions */
00081 
00082 /* I found these on the net a long time ago. They didn't contain any copyright
00083    notice and I couldn't find out where I found them.
00084    If you wrote them please let us know (info@opensg.org) so that we can either
00085    credit you or remove them if you have a problem with us using them.
00086    Thanks
00087             Dirk
00088 */
00089 
00090 static void
00091 rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,
00092 unsigned char *l,int n) 
00093 {
00094     while(n--) 
00095     {
00096         l[0] = r[0];
00097         l[1] = g[0];
00098         l[2] = b[0];
00099         l[3] = a[0];
00100         l += 4; r++; g++; b++; a++;
00101     }
00102 }
00103 
00104 static void
00105 bwtobw(unsigned char *b,unsigned char *l,int n) 
00106 {
00107     memcpy( l, b, n );
00108 }
00109 
00110 static void
00111 latola(unsigned char *b, unsigned char *a,unsigned char *l,int n) 
00112 {
00113     while(n--) 
00114     {
00115         l[0] = *b;
00116         l[1] = *a;
00117         l += 2; b++; a++;
00118     }
00119 }
00120 
00121 static void
00122 rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,
00123     int n) 
00124 {
00125     while(n--) 
00126     {
00127         l[0] = r[0];
00128         l[1] = g[0];
00129         l[2] = b[0];
00130         l += 3; r++; g++; b++;
00131     }
00132 }
00133 
00134 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00135 
00139 struct ImageRec 
00140 {
00141     unsigned short imagic;
00142     unsigned short type;
00143     unsigned short dim;
00144     unsigned short xsize, ysize, zsize;
00145     unsigned int min, max;
00146     unsigned int wasteBytes;
00147     char name[80];
00148     unsigned long colorMap;
00149     FILE *file;
00150     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
00151     unsigned long rleEnd;
00152     unsigned int *rowStart;
00153     int *rowSize;
00154 };
00155 
00156 #endif
00157 
00158 static void
00159 ConvertShort(unsigned short *array, long length) 
00160 {
00161     unsigned b1, b2;
00162     unsigned char *ptr;
00163 
00164     ptr = (unsigned char *)array;
00165     while (length--) 
00166     {
00167         b1 = *ptr++;
00168         b2 = *ptr++;
00169         *array++ = (b1 << 8) | (b2);
00170     }
00171 }
00172 
00173 static void
00174 ConvertLong(unsigned *array, unsigned long length) 
00175 {
00176     unsigned long b1, b2, b3, b4;
00177     unsigned char *ptr;
00178 
00179     ptr = (unsigned char *)array;
00180     while (length--) 
00181     {
00182         b1 = *ptr++;
00183         b2 = *ptr++;
00184         b3 = *ptr++;
00185         b4 = *ptr++;
00186         *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
00187     }
00188 }
00189 
00190 static ImageRec *ImageOpen(const char *fileName)
00191 {
00192     ImageRec *image   = NULL;
00193     FILE     *pInFile = NULL;
00194 
00195     int swapFlag;
00196     int x;
00197 
00198     swapFlag = !osgIsBigEndian();
00199 
00200     if((pInFile = fopen(fileName, "rb")) == NULL) 
00201     {
00202         perror(fileName);
00203         return image;
00204     }
00205 
00206     image = (ImageRec *)malloc(sizeof(ImageRec));
00207 
00208     if (image == NULL) 
00209     {
00210         fprintf(stderr, "Out of memory!\n");
00211         exit(1);
00212     }
00213 
00214     image->file = pInFile;
00215 
00216     fread(image, 1, 12, image->file);
00217 
00218     if (swapFlag) 
00219     {
00220         ConvertShort(&image->imagic, 6);
00221     }
00222 
00223     image->tmp = (unsigned char *)malloc(image->xsize*256);
00224     image->tmpR = (unsigned char *)malloc(image->xsize*256);
00225     image->tmpG = (unsigned char *)malloc(image->xsize*256);
00226     image->tmpB = (unsigned char *)malloc(image->xsize*256);
00227     if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
00228     image->tmpB == NULL) 
00229     {
00230         fprintf(stderr, "Out of memory!\n");
00231         exit(1);
00232     }
00233 
00234     if ((image->type & 0xFF00) == 0x0100) 
00235     {
00236         x = image->ysize * image->zsize * sizeof(unsigned);
00237         image->rowStart = (unsigned *)malloc(x);
00238         image->rowSize = (int *)malloc(x);
00239         if (image->rowStart == NULL || image->rowSize == NULL) 
00240         {
00241             fprintf(stderr, "Out of memory!\n");
00242             exit(1);
00243         }
00244         image->rleEnd = 512 + (2 * x);
00245         fseek(image->file, 512, SEEK_SET);
00246         fread(image->rowStart, 1, x, image->file);
00247         fread(image->rowSize, 1, x, image->file);
00248         if (swapFlag) 
00249         {
00250             ConvertLong(image->rowStart, x/sizeof(unsigned));
00251             ConvertLong((unsigned *)image->rowSize, x/sizeof(int));
00252         }
00253     }
00254     else
00255     {
00256         image->rowStart = NULL;
00257         image->rowSize  = NULL;
00258     }
00259     return image;
00260 }
00261 
00262 static void
00263 ImageClose(ImageRec *image) 
00264 {
00265     fclose(image->file);
00266     free(image->tmp);
00267     free(image->tmpR);
00268     free(image->tmpG);
00269     free(image->tmpB);
00270     if(image->rowStart)
00271         free(image->rowStart);
00272     if(image->rowSize)
00273         free(image->rowSize);
00274     free(image);
00275 }
00276 
00277 static void
00278 ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) 
00279 {
00280     unsigned char *iPtr, *oPtr, pixel;
00281     int count;
00282 
00283     if ((image->type & 0xFF00) == 0x0100) 
00284     {
00285         fseek(image->file, (long)image->rowStart[y+z*image->ysize], SEEK_SET);
00286         fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
00287               image->file);
00288 
00289         iPtr = image->tmp;
00290         oPtr = buf;
00291         for(;;)
00292         {
00293             pixel = *iPtr++;
00294             count = (int)(pixel & 0x7F);
00295             if (!count) 
00296             {
00297                 return;
00298             }
00299             if (pixel & 0x80) 
00300             {
00301                 while (count--) 
00302                 {
00303                     *oPtr++ = *iPtr++;
00304                 }
00305             } 
00306             else 
00307             {
00308                 pixel = *iPtr++;
00309                 while (count--) 
00310                 {
00311                     *oPtr++ = pixel;
00312                 }
00313             }
00314         }
00315     } 
00316     else 
00317     {
00318         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
00319               SEEK_SET);
00320         fread(buf, 1, image->xsize, image->file);
00321     }
00322 }
00323 
00324 /*****************************
00325  *   Types
00326  *****************************/
00327  
00328 // Static Class Varible implementations: 
00329 static const Char8 *suffixArray[] = 
00330 {
00331     "rgb", "rgba", "sgi", "bw"
00332 };
00333 
00334 SGIImageFileType SGIImageFileType::_the ( "sgi",
00335                                           suffixArray,
00336                                           sizeof(suffixArray) );
00337 
00338 
00339 /*****************************
00340  *    Classvariables
00341  *****************************/
00342 
00343 
00344 /********************************
00345  *    Class methodes
00346  *******************************/
00347 
00348 //-------------------------------------------------------------------------
00352 SGIImageFileType& SGIImageFileType::the (void)
00353 {
00354   return _the;
00355 }
00356 
00357 /*******************************
00358 *public
00359 *******************************/
00360 
00361 //-------------------------------------------------------------------------
00366 bool SGIImageFileType::read (ImagePtr &image, const char *fileName )
00367 {
00368  
00369     ImageRec *img = ImageOpen(fileName);
00370     
00371     if(!img)
00372     return false;
00373 
00374     unsigned char *rbuf = (unsigned char *)malloc(img->xsize*
00375                                                     sizeof(unsigned char));
00376     unsigned char *gbuf = (unsigned char *)malloc(img->xsize*
00377                                                     sizeof(unsigned char));
00378     unsigned char *bbuf = (unsigned char *)malloc(img->xsize*
00379                                                     sizeof(unsigned char));
00380     unsigned char *abuf = (unsigned char *)malloc(img->xsize*
00381                                                     sizeof(unsigned char));
00382  
00383     unsigned char *lptr; // pointer to beginning of line in image data
00384     int y;
00385     
00386     switch ( img->zsize )
00387     {
00388     case 1: image->set( Image::OSG_L_PF, img->xsize, img->ysize );
00389             lptr = image->getData();
00390         for(y=0; y<img->ysize; y++) 
00391         {
00392             ImageGetRow(img,rbuf,y,0);
00393             bwtobw(rbuf,lptr,img->xsize);
00394             lptr += img->xsize;
00395         }
00396         break;
00397     case 2: image->set( Image::OSG_LA_PF, img->xsize, img->ysize );
00398             lptr = image->getData();
00399         for(y=0; y<img->ysize; y++) 
00400         {
00401             ImageGetRow(img,rbuf,y,0);
00402             ImageGetRow(img,abuf,y,1);
00403             latola(rbuf,abuf,lptr,img->xsize);
00404             lptr += img->xsize*img->zsize;
00405         }
00406         break;
00407     case 3: image->set( Image::OSG_RGB_PF, img->xsize, img->ysize );
00408             lptr = image->getData();
00409         for(y=0; y<img->ysize; y++) 
00410         {
00411             ImageGetRow(img,rbuf,y,0);
00412             ImageGetRow(img,gbuf,y,1);
00413             ImageGetRow(img,bbuf,y,2);
00414             rgbtorgb(rbuf,gbuf,bbuf,lptr,img->xsize);
00415             lptr += img->xsize*img->zsize;
00416         }
00417         break;
00418     case 4: image->set( Image::OSG_RGBA_PF, img->xsize, img->ysize );
00419             lptr = image->getData();
00420         for(y=0; y<img->ysize; y++) 
00421         {
00422             ImageGetRow(img,rbuf,y,0);
00423             ImageGetRow(img,gbuf,y,1);
00424             ImageGetRow(img,bbuf,y,2);
00425             ImageGetRow(img,abuf,y,3);
00426             rgbatorgba(rbuf,gbuf,bbuf,abuf,lptr,img->xsize);
00427             lptr += img->xsize*img->zsize;
00428         }
00429         break;
00430     default:FWARNING(( "SGIImageFileType::read: unknown zsize %d!", 
00431                 img->zsize));
00432         return false;
00433     }
00434 
00435     ImageClose(img);
00436     free(rbuf);
00437     free(gbuf);
00438     free(bbuf);
00439     free(abuf);
00440 
00441     return true;
00442 }
00443 
00444 //-------------------------------------------------------------------------
00449 bool SGIImageFileType::write(const ImagePtr &  , 
00450                              const char  *OSG_CHECK_ARG(fileName))
00451 { 
00452     FWARNING(("SGIImageFileType::write: not implemented yet!\n"));
00453     return false;
00454 }
00455 
00456 bool SGIImageFileType::validateHeader( const Char8 *fileName, bool &implemented )
00457 {
00458     implemented = true;
00459 
00460     if(fileName == NULL)
00461         return false;
00462 
00463     FILE *file = fopen(fileName, "rb");
00464     if(file == NULL)
00465         return false;
00466 
00467     UInt16 magic = 0;
00468     fread((void *) &magic, sizeof(magic), 1, file);
00469     fclose(file);
00470 
00471 #if BYTE_ORDER == LITTLE_ENDIAN
00472     if(magic == 0xda01) // the magic header is big endian need to swap it.
00473 #else
00474     if(magic == 0x01da)
00475 #endif
00476     {
00477         return true;
00478     }
00479 
00480     return false;
00481 }
00482 
00483 /******************************
00484 *protected
00485 ******************************/
00486 
00487 
00488 /******************************
00489 *private    
00490 ******************************/
00491 
00492 
00493 /***************************
00494 *instance methodes 
00495 ***************************/
00496 
00497 
00498 /***************************
00499 *public
00500 ***************************/
00501 
00502 
00506 //-------------------------------------------------------------------------
00510 SGIImageFileType::SGIImageFileType ( const Char8 *mimeType,
00511                                      const Char8 *suffixArray[], 
00512                                      UInt16 suffixByteCount )
00513     : ImageFileType ( mimeType, suffixArray, suffixByteCount )
00514 {
00515     return;
00516 }
00517 
00518 //-------------------------------------------------------------------------
00522 SGIImageFileType::SGIImageFileType (const SGIImageFileType &obj )
00523     : ImageFileType(obj)
00524 {
00525     return;
00526 }
00527 
00528 //-------------------------------------------------------------------------
00532 SGIImageFileType::~SGIImageFileType (void )
00533 {
00534     return;
00535 }

Generated on Thu Aug 25 04:09:09 2005 for OpenSG by  doxygen 1.4.3