raSystem  1.0 bata
raISGI.cpp
Go to the documentation of this file.
1 #include "..\include\raMain.h"
2 
3 void bwtorgba(unsigned char *b,unsigned char *l,int n)
4 {
5  while (n--) {
6  l[0] = *b;
7  l[1] = *b;
8  l[2] = *b;
9  l[3] = 0xff;
10  l += 4; b++;
11  }
12 }
13 
14 void latorgba(unsigned char *b, unsigned char *a,unsigned char *l,int n)
15 {
16  while (n--) {
17  l[0] = *b;
18  l[1] = *b;
19  l[2] = *b;
20  l[3] = *a;
21  l += 4; b++; a++;
22  }
23 }
24 
25 void rgbtorgba(unsigned char *r,unsigned char *g,
26  unsigned char *b,unsigned char *l,int n)
27 {
28  while (n--) {
29  l[0] = r[0];
30  l[1] = g[0];
31  l[2] = b[0];
32  l[3] = 0xff;
33  l += 4; r++; g++; b++;
34  }
35 }
36 
37 void rgbatorgba(unsigned char *r,unsigned char *g,
38  unsigned char *b,unsigned char *a,unsigned char *l,int n)
39 {
40  while (n--) {
41  l[0] = r[0];
42  l[1] = g[0];
43  l[2] = b[0];
44  l[3] = a[0];
45  l += 4; r++; g++; b++; a++;
46  }
47 }
48 
49 typedef struct _ImageRec {
50  unsigned short imagic;
51  unsigned short type;
52  unsigned short dim;
53  unsigned short xsize, ysize, zsize;
54  unsigned int min, max;
55  unsigned int wasteBytes;
56  char name[80];
57  unsigned long colorMap;
58  FILE *file;
59  unsigned char *tmp, *tmpR, *tmpG, *tmpB;
60  unsigned long rleEnd;
61  unsigned int *rowStart;
62  int *rowSize;
63 } ImageRec;
64 
65 static void ConvertShort(unsigned short *array, long length)
66 {
67  unsigned b1, b2;
68  unsigned char *ptr;
69 
70  ptr = (unsigned char *)array;
71  while (length--) {
72  b1 = *ptr++;
73  b2 = *ptr++;
74  *array++ = (b1 << 8) | (b2);
75  }
76 }
77 
78 static void ConvertLong(unsigned *array, long length)
79 {
80  unsigned b1, b2, b3, b4;
81  unsigned char *ptr;
82 
83  ptr = (unsigned char *)array;
84  while (length--) {
85  b1 = *ptr++;
86  b2 = *ptr++;
87  b3 = *ptr++;
88  b4 = *ptr++;
89  *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
90  }
91 }
92 static ImageRec *ImageOpen(const char *fileName)
93 {
94  union {
95  int testWord;
96  char testByte[4];
97  } endianTest;
98  ImageRec *image;
99  int swapFlag;
100  int x;
101 
102  endianTest.testWord = 1;
103  if (endianTest.testByte[0] == 1) {
104  swapFlag = 1;
105  } else {
106  swapFlag = 0;
107  }
108 
109  image = (ImageRec *)malloc(sizeof(ImageRec));
110  if (image == NULL) {
111  fprintf(stderr, "Out of memory!\n");
112  exit(1);
113  }
114  if ((image->file = fopen(fileName, "rb")) == NULL) {
115  perror(fileName);
116  exit(1);
117  }
118 
119  fread(image, 1, 12, image->file);
120 
121  if (swapFlag) {
122  ConvertShort(&image->imagic, 6);
123  }
124 
125  image->tmp = (unsigned char *)malloc(image->xsize*256);
126  image->tmpR = (unsigned char *)malloc(image->xsize*256);
127  image->tmpG = (unsigned char *)malloc(image->xsize*256);
128  image->tmpB = (unsigned char *)malloc(image->xsize*256);
129  if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
130  image->tmpB == NULL) {
131  fprintf(stderr, "Out of memory!\n");
132  exit(1);
133  }
134 
135  if ((image->type & 0xFF00) == 0x0100) {
136  x = image->ysize * image->zsize * sizeof(unsigned);
137  image->rowStart = (unsigned *)malloc(x);
138  image->rowSize = (int *)malloc(x);
139  if (image->rowStart == NULL || image->rowSize == NULL) {
140  fprintf(stderr, "Out of memory!\n");
141  exit(1);
142  }
143  image->rleEnd = 512 + (2 * x);
144  fseek(image->file, 512, SEEK_SET);
145  fread(image->rowStart, 1, x, image->file);
146  fread(image->rowSize, 1, x, image->file);
147  if (swapFlag) {
148  ConvertLong(image->rowStart, x/(int)sizeof(unsigned));
149  ConvertLong((unsigned *)image->rowSize, x/(int)sizeof(int));
150  }
151  } else {
152  image->rowStart = NULL;
153  image->rowSize = NULL;
154  }
155  return image;
156 }
157 
158 static void ImageClose(ImageRec *image)
159 {
160  fclose(image->file);
161  SAFE_MEMFREE(image->tmp);
162  SAFE_MEMFREE(image->tmpR);
163  SAFE_MEMFREE(image->tmpG);
164  SAFE_MEMFREE(image->tmpB);
165  SAFE_MEMFREE(image->rowSize);
166  SAFE_MEMFREE(image->rowStart);
167  SAFE_MEMFREE(image);
168 }
169 
170 static void ImageGetRow(ImageRec *image,
171  unsigned char *buf, int y, int z)
172 {
173  unsigned char *iPtr, *oPtr, pixel;
174  int count;
175 
176  if ((image->type & 0xFF00) == 0x0100) {
177  fseek(image->file, (long)image->rowStart[y+z*image->ysize], SEEK_SET);
178  fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
179  image->file);
180 
181  iPtr = image->tmp;
182  oPtr = buf;
183  for (;;) {
184  pixel = *iPtr++;
185  count = (int)(pixel & 0x7F);
186  if (!count) {
187  return;
188  }
189  if (pixel & 0x80) {
190  while (count--) {
191  *oPtr++ = *iPtr++;
192  }
193  } else {
194  pixel = *iPtr++;
195  while (count--) {
196  *oPtr++ = pixel;
197  }
198  }
199  }
200  } else {
201  fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
202  SEEK_SET);
203  fread(buf, 1, image->xsize, image->file);
204  }
205 }
206 unsigned char* System::raISGI::LoadSGI(raString name)
207 {
208  unsigned char *base, *lptr;
209  unsigned char *rbuf, *gbuf, *bbuf, *abuf;
210  ImageRec *image;
211  int y;
212 
213  image = ImageOpen(name.c_str());
214 
215  if(!image)
216  return NULL;
217 
218  m_bmpi->bmiHeader.biWidth = image->xsize;
219  m_bmpi->bmiHeader.biHeight = image->ysize;
220  m_zSize = image->zsize;
221 
222  base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned));
223  rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
224  gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
225  bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
226  abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
227  if(!base || !rbuf || !gbuf || !bbuf)
228  return NULL;
229 
230  lptr = base;
231  for (y=0; y<image->ysize; y++) {
232  if (image->zsize>=4) {
233  ImageGetRow(image,rbuf,y,0);
234  ImageGetRow(image,gbuf,y,1);
235  ImageGetRow(image,bbuf,y,2);
236  ImageGetRow(image,abuf,y,3);
237  rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
238  lptr += image->xsize;
239  } else if(image->zsize==3) {
240  ImageGetRow(image,rbuf,y,0);
241  ImageGetRow(image,gbuf,y,1);
242  ImageGetRow(image,bbuf,y,2);
243  rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
244  lptr += image->xsize;
245  } else if(image->zsize==2) {
246  ImageGetRow(image,rbuf,y,0);
247  ImageGetRow(image,abuf,y,1);
248  latorgba(rbuf,abuf,(unsigned char *)lptr,image->xsize);
249  lptr += image->xsize;
250  } else {
251  ImageGetRow(image,rbuf,y,0);
252  bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
253  lptr += image->xsize;
254  }
255  }
256  ImageClose(image);
257  SAFE_MEMFREE(rbuf);
258  SAFE_MEMFREE(gbuf);
259  SAFE_MEMFREE(bbuf);
260  SAFE_MEMFREE(abuf);
261 
262  return base;
263 }
unsigned int max
Definition: raISGI.cpp:54
void rgbatorgba(unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a, unsigned char *l, int n)
Definition: raISGI.cpp:37
unsigned short type
Definition: raISGI.cpp:51
void bwtorgba(unsigned char *b, unsigned char *l, int n)
Definition: raISGI.cpp:3
unsigned char * tmp
Definition: raISGI.cpp:59
#define SAFE_MEMFREE(x)
Definition: raMain.h:126
unsigned long rleEnd
Definition: raISGI.cpp:60
struct _ImageRec ImageRec
unsigned short xsize
Definition: raISGI.cpp:53
unsigned char * tmpR
Definition: raISGI.cpp:59
int * rowSize
Definition: raISGI.cpp:62
unsigned char * tmpG
Definition: raISGI.cpp:59
unsigned short ysize
Definition: raISGI.cpp:53
unsigned long colorMap
Definition: raISGI.cpp:57
std::string raString
Definition: raMain.h:107
FILE * file
Definition: raISGI.cpp:58
void rgbtorgba(unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *l, int n)
Definition: raISGI.cpp:25
unsigned int * rowStart
Definition: raISGI.cpp:61
unsigned short zsize
Definition: raISGI.cpp:53
unsigned char * tmpB
Definition: raISGI.cpp:59
unsigned short imagic
Definition: raISGI.cpp:50
unsigned short dim
Definition: raISGI.cpp:52
unsigned int min
Definition: raISGI.cpp:54
void latorgba(unsigned char *b, unsigned char *a, unsigned char *l, int n)
Definition: raISGI.cpp:14
char name[80]
Definition: raISGI.cpp:56
unsigned int wasteBytes
Definition: raISGI.cpp:55