--- /dev/null
+/*
+Copyright (C) 1999-2006 Id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+
+#include "radiant_jpeglib.h"
+#include "jerror.h"
+#include <memory.h>
+
+GLOBAL int LoadJPGBuff(unsigned char *fbuffer, int bufsize, unsigned char **pic, int *width, int *height )
+{
+
+ /* 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.
+ * Note that this struct must live as long as the main JPEG parameter
+ * struct, to avoid dangling-pointer problems.
+ */
+ /* This struct represents a JPEG error handler. It is declared separately
+ * because applications often want to supply a specialized error handler
+ * (see the second half of this file for an example). But here we just
+ * take the easy way out and use the standard error handler, which will
+ * print a message on stderr and call exit() if compression fails.
+ * Note that this struct must live as long as the main JPEG parameter
+ * struct, to avoid dangling-pointer problems.
+ */
+
+ struct jpeg_error_mgr jerr;
+ /* More stuff */
+ JSAMPARRAY buffer; /* Output row buffer */
+ int row_stride; /* physical row width in output buffer */
+ unsigned char *out, *bbuf;
+ int nSize;
+ int jmpret;
+ int i;
+
+ // Rad additions: initialize the longjmp buffer
+ jmpret = setjmp( rad_loadfailed );
+ if (jmpret != 0)
+ {
+ *pic = (unsigned char *)rad_errormsg;
+ return -1;
+ }
+
+ /* Step 1: allocate and initialize JPEG decompression object */
+
+ /* We have to set up the error handler first, in case the initialization
+ * step fails. (Unlikely, but it could happen if you are out of memory.)
+ * This routine fills in the contents of struct jerr, and returns jerr's
+ * address which we place into the link field in cinfo.
+ */
+ cinfo.err = jpeg_std_error(&jerr);
+
+ /* Now we can initialize the JPEG decompression object. */
+ jpeg_create_decompress(&cinfo);
+
+ /* Step 2: specify data source (eg, a file) */
+
+ jpeg_stdio_src(&cinfo, fbuffer, bufsize);
+
+ /* Step 3: read file parameters with jpeg_read_header() */
+
+ (void) jpeg_read_header(&cinfo, TRUE);
+ /* We can ignore the return value from jpeg_read_header since
+ * (a) suspension is not possible with the stdio data source, and
+ * (b) we passed TRUE to reject a tables-only JPEG file as an error.
+ * See libjpeg.doc for more info.
+ */
+
+ /* Step 4: set parameters for decompression */
+
+ /* In this example, we don't need to change any of the defaults set by
+ * jpeg_read_header(), so we do nothing here.
+ */
+
+ /* Step 5: Start decompressor */
+
+ (void) jpeg_start_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ if( cinfo.output_components != 1 && cinfo.output_components != 3 && cinfo.output_components != 4 )
+ {
+ *pic = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>("Non-Y/RGB/RGBA JPEG encountered (unsupported)"));
+ return -1;
+ }
+
+ /* We may need to do some setup of our own at this point before reading
+ * the data. After jpeg_start_decompress() we have the correct scaled
+ * output image dimensions available, as well as the output colormap
+ * if we asked for color quantization.
+ * In this example, we need to make an output work buffer of the right size.
+ */
+
+ /* JSAMPLEs per row in output buffer */
+ row_stride = cinfo.output_width * cinfo.output_components;
+ nSize = cinfo.output_width*cinfo.output_height*4;
+
+ out = reinterpret_cast<unsigned char*>( malloc( nSize+ 1 ) );
+ memset( out, 255, nSize + 1 );
+
+ *pic = out;
+ *width = cinfo.output_width;
+ *height = cinfo.output_height;
+
+ /* Step 6: while (scan lines remain to be read) */
+ /* jpeg_read_scanlines(...); */
+
+ /* Here we use the library's state variable cinfo.output_scanline as the
+ * loop counter, so that we don't have to keep track ourselves.
+ */
+ while (cinfo.output_scanline < cinfo.output_height)
+ {
+ /* jpeg_read_scanlines expects an array of pointers to scanlines.
+ * Here the array is only one element long, but you could ask for
+ * more than one scanline at a time if that's more convenient.
+ */
+ bbuf = out + row_stride * cinfo.output_scanline;
+ buffer = &bbuf;
+ (void) jpeg_read_scanlines( &cinfo, buffer, 1 );
+
+ // we convert downwards to not overwrite values we want to read later
+ switch(cinfo.output_components)
+ {
+ case 4:
+ // clear all the alphas to 255
+ for(i = cinfo.output_width; i-- > 0; )
+ {
+ bbuf[i*4+3] = 255;
+ }
+ break;
+ case 3:
+ // expand 3 to 4
+ for(i = cinfo.output_width; i-- > 0; )
+ {
+ bbuf[i*4+3] = 255;
+ bbuf[i*4+2] = bbuf[i*3+2];
+ bbuf[i*4+1] = bbuf[i*3+1];
+ bbuf[i*4+0] = bbuf[i*3+0];
+ }
+ break;
+ case 1:
+ // expand 1 to 4
+ for(i = cinfo.output_width; i-- > 0; )
+ {
+ bbuf[i*4+3] = 255;
+ bbuf[i*4+2] = bbuf[i];
+ bbuf[i*4+1] = bbuf[i];
+ bbuf[i*4+0] = bbuf[i];
+ }
+ break;
+ }
+ }
+
+ /* Step 7: Finish decompression */
+
+ (void) jpeg_finish_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ /* Step 8: Release JPEG decompression object */
+
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_decompress(&cinfo);
+
+ /* After finish_decompress, we can close the input file.
+ * Here we postpone it until after no more JPEG errors are possible,
+ * so as to simplify the setjmp error logic above. (Actually, I don't
+ * think that jpeg_destroy can do an error exit, but why assume anything...)
+ */
+ //free (fbuffer);
+
+ /* At this point you may want to check to see whether any corrupt-data
+ * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+ */
+
+ /* And we're done! */
+ return 0;
+}