25 #ifdef SIMAGE_RGB_SUPPORT
33 #define ERR_NO_ERROR 0
38 #define ERR_OPEN_WRITE 5
48 unsigned int * rowseek;
50 unsigned char * rlebuf;
52 unsigned char * tmpbuf[4];
53 } simage_rgb_opendata;
61 simage_rgb_opendata * od = (simage_rgb_opendata*)
66 int bpr = *width * *numcomponents;
67 unsigned char * buf = (
unsigned char *) malloc((
size_t)bpr * *height);
69 for (i = 0; i < *height; i++) {
84 write_short(FILE * fp,
unsigned short val)
87 tmp[0] = (
unsigned char)(val >> 8);
88 tmp[1] = (
unsigned char)(val & 0xff);
89 return (
int)fwrite(&tmp, 2, 1, fp);
94 const unsigned char * bytes,
100 unsigned char * tmpbuf;
101 unsigned char buf[500];
103 FILE * fp = fopen(filename,
"wb");
109 write_short(fp, 0x01da);
110 write_short(fp, 0x0001);
113 write_short(fp, 0x0002);
115 write_short(fp, 0x0003);
117 write_short(fp, (
unsigned short) width);
118 write_short(fp, (
unsigned short) height);
119 write_short(fp, (
unsigned short) comp);
123 strcpy((
char *)buf+8,
"https://coin3d.github.io");
124 fwrite(buf, 1, 500, fp);
126 tmpbuf = (
unsigned char *) malloc(width);
128 for (c = 0; c < comp; c++) {
129 for (y = 0; y < height; y++) {
130 for (x = 0; x < width; x++) {
131 tmpbuf[x] = bytes[x * comp + y * comp * width + c];
133 fwrite(tmpbuf, 1, width, fp);
143 const unsigned char * header,
146 static unsigned char rgbcmp[] = {0x01, 0xda};
147 if (headerlen < 2)
return 0;
148 if (memcmp((
const void*)header,
149 (
const void*)rgbcmp, 2) == 0)
return 1;
158 strncpy(buffer,
"RGB loader: Error opening file", buflen);
161 strncpy(buffer,
"RGB loader: Error reading file", buflen);
164 strncpy(buffer,
"RGB loader: Out of memory error", buflen);
167 strncpy(buffer,
"RGB loader: Unsupported zsize", buflen);
170 strncpy(buffer,
"RGB loader: Error opening file for writing", buflen);
176 read_short(FILE * in,
short * dst,
int n,
int swap)
181 int num = (int)fread(dst,
sizeof(
short), n, in);
182 if (num == n && swap) {
183 ptr = (
unsigned char *) dst;
184 for (i = 0; i < n; i++) {
195 read_ushort(FILE * in,
unsigned short * dst,
int n,
int swap)
197 return read_short(in, (
short*) dst, n, swap);
201 read_int(FILE * in,
int * dst,
int n,
int swap)
206 int num = (int)fread(dst,
sizeof(
int), n, in);
207 if (num == n && swap) {
208 ptr = (
unsigned char *) dst;
209 for (i = 0; i < n; i++) {
223 read_uint(FILE * in,
unsigned int * dst,
int n,
int swap)
225 return read_int(in, (
int*)dst, n, swap);
238 unsigned short size[3];
239 simage_rgb_opendata * od;
248 swap = endiantest.bytedata[0] == 1;
250 in = fopen(filename,
"rb");
256 (void) fseek(in, 2, SEEK_SET);
257 if (!read_ushort(in, &type, 1, swap)) {
263 (void) fseek(in, 6, SEEK_SET);
264 if (!read_ushort(in, size, 3, swap)) {
270 od = (simage_rgb_opendata*) malloc(
sizeof(simage_rgb_opendata));
271 memset(od, 0,
sizeof(simage_rgb_opendata));
273 od->w = (int) size[0];
274 od->h = (int) size[1];
275 od->nc = (int) size[2];
276 od->compressed = (type & 0xFF00) == 0x0100;
277 od->rlebuf = (
unsigned char*) malloc(od->w * 2);
278 od->rlebuflen = od->w * 2;
280 for (i = 0; i < od->nc; i++) {
281 od->tmpbuf[i] = (
unsigned char *) malloc(od->w);
283 if (od->compressed) {
285 int numlookup = od->h * od->nc;
286 od->rowseek = (
unsigned int*) malloc(numlookup * 4);
287 od->rowlen = (
int*) malloc(numlookup * 4);
289 (void) fseek(in, 512, SEEK_SET);
290 (void) read_uint(in, od->rowseek, numlookup, swap);
291 if (!read_int(in, od->rowlen, numlookup, swap)) {
299 *numcomponents = od->nc;
307 simage_rgb_opendata * od =
308 (simage_rgb_opendata*) opendata;
311 for (i = 0; i < od->nc; i++) {
314 if (od->rowseek) free(od->rowseek);
315 if (od->rowlen) free(od->rowlen);
316 if (od->rlebuf) free(od->rlebuf);
321 read_rgb_row_component(simage_rgb_opendata * od,
int y,
int c)
323 if (od->compressed) {
324 unsigned char * src, * dst;
325 unsigned char * srcstop, * dststop;
330 if (fseek(od->in, od->rowseek[y+c*od->h], SEEK_SET) != 0) {
334 rowlen = od->rowlen[y+c*od->h];
335 if (rowlen > od->rlebuflen) {
337 od->rlebuflen = rowlen;
338 od->rlebuf = (
unsigned char*) malloc(od->rlebuflen);
340 if (fread(od->rlebuf, 1, rowlen, od->in) != rowlen) {
347 srcstop = src + rowlen;
348 dststop = dst + od->w;
351 count = (int)(pixel & 0x7F);
354 if (dst + count > dststop) { rgberror =
ERR_READ;
return 0; }
356 if (src + count > srcstop) { rgberror =
ERR_READ;
return 0; }
362 if (src >= srcstop) { rgberror =
ERR_READ;
return 0; }
369 count = (int)(pixel & 0x7F);
373 if (fseek(od->in, 512+(y*od->w)+(c*od->w*od->h), SEEK_SET) != 0) {
377 if (fread(od->tmpbuf[c], 1, od->w, od->in) != od->w) {
391 simage_rgb_opendata * od =
392 (simage_rgb_opendata*) opendata;
395 for (c = 0; c < od->nc; c++) {
396 if (!read_rgb_row_component(od, y, c)) {
404 for (i = 0; i < od->w; i++) {
405 for (c = 0; c < od->nc; c++) {
406 *ptr++ = od->tmpbuf[c][i];
unsigned char * simage_rgb_load(const char *filename, int *width, int *height, int *numcomponents)
int simage_rgb_read_line(void *opendata, int y, unsigned char *buf)
int simage_rgb_save(const char *filename, const unsigned char *bytes, int width, int height, int numcomponents)
void simage_rgb_close(void *opendata)
int simage_rgb_error(char *buffer, int bufferlen)
int simage_rgb_identify(const char *filename, const unsigned char *header, int headerlen)
void * simage_rgb_open(const char *filename, int *width, int *height, int *numcomponents)