00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
00081
00082
00083
00084
00085
00086
00087
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
00326
00327
00328
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
00341
00342
00343
00344
00345
00346
00347
00348
00352 SGIImageFileType& SGIImageFileType::the (void)
00353 {
00354 return _the;
00355 }
00356
00357
00358
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;
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)
00473 #else
00474 if(magic == 0x01da)
00475 #endif
00476 {
00477 return true;
00478 }
00479
00480 return false;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
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 }