Back to index

extremetuxracer  0.5beta
rgb_reader.cpp
Go to the documentation of this file.
00001 /* 
00002  * PPRacer 
00003  * Copyright (C) 2004-2005 Volker Stroebel <volker@planetpenguin.de>
00004  *
00005  * Copyright (C) 1999-2001 Jasmin F. Patry
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 /* This code taken from Mesa 3Dfx demos by David Bucciarelli (tech.hmw@plus.it)
00023  */
00024  
00025 #include "rgb_reader.h"
00026 
00027  
00028 #define IMAGIC      0x01da
00029 #define IMAGIC_SWAP 0xda01
00030 
00031 #define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
00032 #define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \
00033 ((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)))
00034 
00035 namespace pp{ 
00036  
00037 ReaderRGB::ReaderRGB(const char* fileName)
00038 {
00039        ImageInfo *image;
00040        //IMAGEInfo *final;
00041        int sx;
00042 
00043        image = ImageOpen(fileName);
00044 
00045        if ( image == NULL ) {
00046               return;
00047        }
00048 
00049        width=image->sizeX; 
00050        height= image->sizeY;
00051        depth= image->sizeZ;
00052 
00053   /* 
00054    * Round up so rows are long-word aligned 
00055    */
00056   sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2;
00057 
00058   data 
00059     = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int));
00060 
00061   if (data == NULL) 
00062     {
00063       fprintf(stderr, "Out of memory!\n");
00064       //winsys_exit(-1);
00065          return;
00066     }
00067 
00068   ImageGetRawData(image, data);
00069   ImageClose(image);
00070 }
00071 
00072 ReaderRGB::ImageInfo*
00073 ReaderRGB::ImageOpen(const char *fileName)
00074 {
00075   ImageInfo *image;
00076   unsigned int *rowStart, *rowSize, ulTmp;
00077   int x, i;
00078 
00079   image = (ImageInfo *)malloc(sizeof(ImageInfo));
00080   if (image == NULL) 
00081     {
00082       fprintf(stderr, "Out of memory!\n");
00083       //winsys_exit(-1);
00084     }
00085   if ((image->file = fopen(fileName, "rb")) == NULL) 
00086     {
00087       free( image );
00088       return NULL;
00089     }
00090   /*
00091    *   Read the image header
00092    */
00093   fread(image, 1, 12, image->file);
00094   /*
00095    *   Check byte order
00096    */
00097   if (image->imagic == IMAGIC_SWAP) 
00098     {
00099       image->type = SWAP_SHORT_BYTES(image->type);
00100       image->dim = SWAP_SHORT_BYTES(image->dim);
00101       image->sizeX = SWAP_SHORT_BYTES(image->sizeX);
00102       image->sizeY = SWAP_SHORT_BYTES(image->sizeY);
00103       image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ);
00104     }
00105 
00106   for ( i = 0 ; i <= image->sizeZ ; i++ )
00107     {
00108       image->tmp[i] = (unsigned char *)malloc(image->sizeX*256);
00109       if (image->tmp[i] == NULL ) 
00110        {
00111          fprintf(stderr, "Out of memory!\n");
00112          //winsys_exit(-1);
00113        }
00114     }
00115 
00116   if ((image->type & 0xFF00) == 0x0100) /* RLE image */
00117     {
00118       x = image->sizeY * image->sizeZ * sizeof(int);
00119       image->rowStart = (unsigned int *)malloc(x);
00120       image->rowSize = (unsigned int *)malloc(x);
00121       if (image->rowStart == NULL || image->rowSize == NULL) 
00122        {
00123          fprintf(stderr, "Out of memory!\n");
00124          //winsys_exit(-1);
00125        }
00126       image->rleEnd = 512 + (2 * x);
00127       fseek(image->file, 512, SEEK_SET);
00128       fread(image->rowStart, 1, x, image->file);
00129       fread(image->rowSize, 1, x, image->file);
00130       if (image->imagic == IMAGIC_SWAP) 
00131        {
00132          x /= sizeof(int);
00133          rowStart = image->rowStart;
00134          rowSize = image->rowSize;
00135          while (x--) 
00136            {
00137              ulTmp = *rowStart;
00138              *rowStart++ = SWAP_LONG_BYTES(ulTmp);
00139              ulTmp = *rowSize;
00140              *rowSize++ = SWAP_LONG_BYTES(ulTmp);
00141            }
00142        }
00143     }
00144   return image;
00145 }
00146 
00147 void
00148 ReaderRGB::ImageGetRawData( ImageInfo *image, unsigned char *data)
00149 {
00150   int i, j, k;
00151   int remain = 0;
00152 
00153   switch ( image->sizeZ )
00154     {
00155     case 1:
00156       remain = image->sizeX % 4;
00157       break;
00158     case 2:
00159       remain = image->sizeX % 2;
00160       break;
00161     case 3:
00162       remain = (image->sizeX * 3) & 0x3;
00163       if (remain)
00164        remain = 4 - remain;
00165       break;
00166     case 4:
00167       remain = 0;
00168       break;
00169     }
00170 
00171   for (i = 0; i < image->sizeY; i++) 
00172     {
00173       for ( k = 0; k < image->sizeZ ; k++ )
00174        ImageGetRow(image, image->tmp[k+1], i, k);
00175       for (j = 0; j < image->sizeX; j++) 
00176        for ( k = 1; k <= image->sizeZ ; k++ )
00177          *data++ = *(image->tmp[k] + j);
00178       data += remain;
00179     }
00180 }
00181 
00182 void
00183 ReaderRGB::ImageGetRow( ImageInfo *image, unsigned char *buf, int y, int z)
00184 {
00185   unsigned char *iPtr, *oPtr, pixel;
00186   int count;
00187 
00188   if ((image->type & 0xFF00) == 0x0100)  /* RLE image */
00189     {
00190       fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET);
00191       fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY],
00192            image->file);
00193 
00194       iPtr = image->tmp[0];
00195       oPtr = buf;
00196       while (1) 
00197        {
00198          pixel = *iPtr++;
00199          count = (int)(pixel & 0x7F);
00200          if (!count)
00201            return;
00202          if (pixel & 0x80) 
00203            {
00204              while (count--) 
00205               {
00206                 *oPtr++ = *iPtr++;
00207               }
00208            } 
00209          else 
00210            {
00211              pixel = *iPtr++;
00212              while (count--) 
00213               {
00214                 *oPtr++ = pixel;
00215               }
00216            }
00217        }
00218     }
00219   else /* verbatim image */
00220     {
00221       fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY),
00222            SEEK_SET);
00223       fread(buf, 1, image->sizeX, image->file);
00224     }
00225 }
00226 
00227 void
00228 ReaderRGB::ImageClose( ImageInfo *image)
00229 {
00230   int i;
00231 
00232   fclose(image->file);
00233   for ( i = 0 ; i <= image->sizeZ ; i++ )
00234     free(image->tmp[i]);
00235   free(image);
00236 }
00237  
00238 } //namespace pp