SbBool ReadGIFImage(const SoInput& in, int &w, int &h, int &nc, unsigned char *&bytes) { int ncolors; int bgIndex; int errCode; XColor *colors = (XColor*) malloc(GIF_MAXCOLORMAPSIZE * sizeof(XColor)); FILE *fp = in.getCurFile(); fseek(fp, 0, SEEK_SET); if (fp == NULL) return FALSE; unsigned char *array = readGIF(fp, &w, &h, colors, &ncolors, &bgIndex, &errCode); if (errCode != GIF_NO_ERROR) { free(colors); return FALSE; } nc = 3; // convert color map image to rgb // gif files go top down and we need bottom up. Switch it. bytes = new unsigned char[w*h*nc]; int i, j; for (j = 0; j < h; ++j) for (i = 0; i < w; ++i) { int c = array[j*w+i]; int index = ((h-j-1)*w+i)*nc; if (c < 0 || c >= ncolors) // store black if out of range bytes[index] = bytes[index+1] = bytes[index+2] = 0; else { bytes[index] = colors[c].red / 256; bytes[index+1] = colors[c].green / 256; bytes[index+2] = colors[c].blue / 256; } } free(colors); free(array); return TRUE; }
SbBool ReadSGIImage(const SoInput& in, int &w, int &h, int &nc, unsigned char *&bytes) { i_seterror(errfunc); IMAGE *image_in; int i, j, row; if ( (image_in = fiopen(fileno(in.getCurFile()), "r")) == NULL) return FALSE; w = image_in->xsize; h = image_in->ysize; nc = image_in->zsize; bytes = new unsigned char[w*h*nc]; short *rbuf = new short[w]; int readOK = TRUE; for (row = 0; row < h; row++) { for (i = 0; i < nc; i++) { if (getrow(image_in, rbuf, row, i) < 0) { row = h; // Don't read any more rows readOK = FALSE; break; } for (j = 0; j < w; j++) { bytes[row*w*nc + j*nc + i] = (unsigned char) rbuf[j]; } } } delete [] rbuf; iclose(image_in); return TRUE; }
SbBool ReadJPEGImage(const SoInput& in, int &w, int &h, int &nc, unsigned char *&bytes) { /* This struct contains the JPEG decompression parameters and pointers to * working space (which is allocated as needed by the JPEG library). */ struct jpeg_decompress_struct cinfo; /* We use our private extension JPEG error handler. */ struct my_error_mgr jerr; /* More stuff */ FILE * infile; /* source file */ JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ infile = in.getCurFile(); fseek(infile, 0, SEEK_SET); /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_decompress(&cinfo); return FALSE; } /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress(&cinfo); /* Step 2: specify data source (eg, a file) */ jpeg_stdio_src(&cinfo, infile); /* Step 3: read file parameters with jpeg_read_header() */ jpeg_read_header(&cinfo, TRUE); /* Step 5: Start decompressor */ jpeg_start_decompress(&cinfo); // make buffer for data to be put into w = cinfo.output_width; h = cinfo.output_height; nc = cinfo.output_components; bytes = new unsigned char[w*h*nc]; row_stride = w*nc; /* Make a one-row-high sample array that will go away when done with image */ buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); unsigned char *curline = bytes+(h-1)*w*nc; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, buffer, 1); // put the data from the sample buffer into the output buffer for (int i = 0; i < row_stride; ++i) curline[i] = (unsigned char) (buffer[0][i]); curline -= w*nc; } /* Step 7: Finish decompression */ jpeg_finish_decompress(&cinfo); /* Step 8: Release JPEG decompression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress(&cinfo); /* At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ return TRUE; }