1 /* NIGHTFALL OpenGL Interface                                              */
2 /* Copyright (C) 2001 Rainer Wichmann & Markus Kuster                      */
3 /*                                                                         */
4 /*  This program is free software; you can redistribute it                 */
5 /*  and/or modify                                                          */
6 /*  it under the terms of the GNU General Public License as                */
7 /*  published by                                                           */
8 /*  the Free Software Foundation; either version 2 of the License, or      */
9 /*  (at your option) any later version.                                    */
10 /*
11                                                                 */
12 /*  This program is distributed in the hope that it will be useful,        */
13 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
14 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
15 /*  GNU General Public License for more details.                           */
16 /*                                                                         */
17 /*  You should have received a copy of the GNU General Public License      */
18 /*  along with this program; if not, write to the Free Software            */
19 /*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
20 
21 /* ANSI C forbids an empty source file, so put this outside                */
22 /* do nothing here if we don't have OpenGL                                 */
23 
24 #include <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "Light.h"
29 
30 #ifdef  _WITH_OPENGL
31 #include <setjmp.h>
32 #include <GL/glut.h>
33 
34 struct my_error_mgr {
35   struct jpeg_error_mgr pub;	/* "public" fields */
36   jmp_buf setjmp_buffer;	/* for return to caller */
37 };
38 
39 typedef struct my_error_mgr * my_error_ptr;
40 
41 /*
42  * Here's the routine that will replace the standard error_exit method:
43  */
44 
45 METHODDEF(void)
my_error_exit(j_common_ptr cinfo)46 my_error_exit (j_common_ptr cinfo)
47 {
48   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
49   my_error_ptr myerr = (my_error_ptr) cinfo->err;
50 
51   /* Always display the message. */
52   /* We could postpone this until after returning, if we chose. */
53   (*cinfo->err->output_message) (cinfo);
54 
55   /* Return control to the setjmp point */
56   longjmp(myerr->setjmp_buffer, 1);
57 }
58 
59 /******************************************************************
60  @package   nightfall
61  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
62  @version   1.0
63  @short     Read a JPEG coded image file
64  @param     (char) *filename   the name of the image file
65             (int)  *width      pointer to the variable to store the
66                                width of the image
67 	    (int)  *height     pointer to the variable to store the
68                                height of the image
69 	    (int)  *components number of color components per pixel
70  @return    (GLubyte) *buffer  pointer to the image buffer
71                                containing the image
72  @heading Read a JPEG image from a file and decompress it. This code
73           is based on the example code example.c included in the
74           jpeg-library libjpeg-6.2.0.
75 *******************************************************************/
ReadJPEGFile(char * filename,int * width,int * height,int * components)76 GLubyte *ReadJPEGFile(char *filename, int *width, int *height, int *components)
77 {
78   /* This struct contains the JPEG decompression parameters and pointers to
79    * working space (which is allocated as needed by the JPEG library).
80    */
81   struct jpeg_decompress_struct cinfo;
82   /* We use our private extension JPEG error handler.
83    * Note that this struct must live as long as the main JPEG parameter
84    * struct, to avoid dangling-pointer problems.
85    */
86   struct my_error_mgr jerr;
87   /* More stuff */
88   FILE * infile;		/* source file */
89   JSAMPARRAY buffer;		/* Output row buffer */
90   JSAMPLE *image_buffer;        /* Array of R,G,B-order data */
91   char ErrMsg[256];             /* error message          */
92 
93   int row_stride;		/* physical row width in output buffer */
94   long cont;
95 
96   /* In this example we want to open the input file before doing anything else,
97    * so that the setjmp() error recovery below can assume the file is open.
98    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
99    * requires it in order to read binary files.
100    */
101 
102   if (!(infile = fopen(filename, "rb"))) {
103     sprintf(ErrMsg,_("Can't open jpeg file: %s \n"),filename);
104     WARNING (ErrMsg);
105     return(FALSE);
106   }
107 
108   /* Step 1: allocate and initialize JPEG decompression object */
109 
110   /* We set up the normal JPEG error routines, then override error_exit. */
111   cinfo.err = jpeg_std_error(&jerr.pub);
112   jerr.pub.error_exit = my_error_exit;
113   /* Establish the setjmp return context for my_error_exit to use. */
114 
115   if (setjmp(jerr.setjmp_buffer)) {
116     /* If we get here, the JPEG code has signaled an error.
117      * We need to clean up the JPEG object, close the input file, and return.
118      */
119     sprintf(ErrMsg,_("JPEG code has signaled an error ! \n"));
120     WARNING (ErrMsg);
121 
122     jpeg_destroy_decompress(&cinfo);
123     fclose(infile);
124     return(FALSE);
125   }
126   /* Now we can initialize the JPEG decompression object. */
127   jpeg_create_decompress(&cinfo);
128 
129   /* Step 2: specify data source (eg, a file) */
130 
131   jpeg_stdio_src(&cinfo, infile);
132 
133   /* Step 3: read file parameters with jpeg_read_header() */
134 
135   (void) jpeg_read_header(&cinfo, TRUE);
136 
137   /* We can ignore the return value from jpeg_read_header since
138    *   (a) suspension is not possible with the stdio data source, and
139    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
140    * See libjpeg.doc for more info.
141    */
142 
143   /* Step 4: set parameters for decompression */
144 
145   /* In this example, we don't need to change any of the defaults set by
146    * jpeg_read_header(), so we do nothing here.
147    */
148 
149   /* Step 5: Start decompressor */
150 
151   (void) jpeg_start_decompress(&cinfo);
152   /* We can ignore the return value since suspension is not possible
153    * with the stdio data source.
154    */
155 
156   /* We may need to do some setup of our own at this point before reading
157    * the data.  After jpeg_start_decompress() we have the correct scaled
158    * output image dimensions available, as well as the output colormap
159    * if we asked for color quantization.
160    * In this example, we need to make an output work buffer of the right size.
161    */
162   /* JSAMPLEs per row in output buffer */
163   row_stride = cinfo.output_width * cinfo.output_components;
164 
165   /* Make a one-row-high sample array that will go away when done with image */
166   buffer = (*cinfo.mem->alloc_sarray)
167     ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
168 
169   /* Allocate buffer for the full image */
170   image_buffer=(JSAMPLE *) malloc(cinfo.image_width*cinfo.image_height*cinfo.output_components);
171   if (!image_buffer) {
172     sprintf(ErrMsg,_("Can't allocate memory for image buffer !\n"));
173     WARNING (ErrMsg);
174     /* clean up and return savely */
175     jpeg_destroy_decompress(&cinfo);
176     fclose(infile);
177     return(FALSE);
178   }
179 
180   /* Step 6: while (scan lines remain to be read) */
181   /*           jpeg_read_scanlines(...); */
182 
183   /* Here we use the library's state variable cinfo.output_scanline as the
184    * loop counter, so that we don't have to keep track ourselves.
185    */
186 
187   cont=cinfo.output_height-1;
188   while (cinfo.output_scanline < cinfo.output_height) {
189     /* jpeg_read_scanlines expects an array of pointers to scanlines.
190      * Here the array is only one element long, but you could ask for
191      * more than one scanline at a time if that's more convenient.
192      */
193     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
194     /* copy buffer to the image storage area */
195     memcpy(image_buffer+cinfo.image_width*cinfo.output_components*cont,buffer[0],row_stride);
196     cont--;
197   }
198 
199   /* Step 7: Finish decompression */
200 
201   (void) jpeg_finish_decompress(&cinfo);
202   /* We can ignore the return value since suspension is not possible
203    * with the stdio data source.
204    */
205 
206   /* Step 8: Release JPEG decompression object */
207 
208   /* This is an important step since it will release a good deal of memory. */
209   jpeg_destroy_decompress(&cinfo);
210 
211   /* After finish_decompress, we can close the input file.
212    * Here we postpone it until after no more JPEG errors are possible,
213    * so as to simplify the setjmp error logic above.  (Actually, I don't
214    * think that jpeg_destroy can do an error exit, but why assume anything...)
215    */
216   if (infile) {
217     fclose(infile);
218   }
219 
220   /* store number of color components per pixel */
221   *components=cinfo.output_components;
222 
223   /* store image width and height */
224   *width=cinfo.image_width;
225   *height=cinfo.image_height;
226 
227 
228   /* At this point you may want to check to see whether any corrupt-data
229    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
230    */
231 
232   /* And we're done! */
233   return image_buffer;
234 }
235 
236 /******************************************************************
237  @package   nightfall
238  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
239  @version   1.0
240  @short     Write a JPEG coded image file
241  @param     (char) *filename   the name of the image file
242             (int)  *width      pointer to the variable to store the
243                                width of the image
244 	    (int)  *height     pointer to the variable to store the
245                                height of the image
246 	    (int)  *components number of color components per pixel
247  @return    (GLubyte) *buffer  pointer to the image buffer
248                                containing the image
249  @heading Compress a byte image and write it as jpeg file. This code
250           is based on the example code example.c included in the
251           jpeg-library libjpeg-6.2.0.
252 *******************************************************************/
WriteJPEGFile(JSAMPLE * imgbuff,char * filename,int imgwidth,int imgheight,int components,int quality)253 int WriteJPEGFile(JSAMPLE * imgbuff, char *filename, int imgwidth,
254 		    int imgheight, int components, int quality)
255 {
256   /* This struct contains the JPEG compression parameters and pointers to
257    * working space (which is allocated as needed by the JPEG library).
258    * It is possible to have several such structures, representing multiple
259    * compression/decompression processes, in existence at once.  We refer
260    * to any one struct (and its associated working data) as a "JPEG object".
261    */
262   struct jpeg_compress_struct cinfo;
263   /* This struct represents a JPEG error handler. It is declared separately
264    * because applications often want to supply a specialized error handler
265    * (see the second half of this file for an example).  But here we just
266    * take the easy way out and use the standard error handler, which will
267    * print a message on stderr and call exit() if compression fails.
268    * Note that this struct must live as long as the main JPEG parameter
269    * struct, to avoid dangling-pointer problems.
270    */
271   struct my_error_mgr jerr;
272   JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
273   int row_stride,line;          /* physical row width in image buffer */
274   FILE *outfile;                /* image file */
275   char ErrMsg[256];             /* error message          */
276 
277   /* open output file */
278   if (!(outfile = fopen(filename, "wb"))) {
279     sprintf(ErrMsg,_("Can't write jpeg file: %s \n"),filename);
280     WARNING (ErrMsg);
281     return(FALSE);
282   }
283 
284   /* Step 1: allocate and initialize JPEG compression object */
285 
286   /* We have to set up the error handler first, in case the initialization
287    * step fails.  (Unlikely, but it could happen if you are out of memory.)
288    * This routine fills in the contents of struct jerr, and returns jerr's
289    * address which we place into the link field in cinfo.
290    */
291 
292   /* error handler
293    */
294   cinfo.err = jpeg_std_error(&jerr.pub);
295   jerr.pub.error_exit = my_error_exit;
296 
297   if (setjmp(jerr.setjmp_buffer)) {
298     /* If we get here, the JPEG code has signaled an error.
299      * We need to clean up the JPEG object, close the input file, and return.
300      */
301     sprintf(ErrMsg,_("JPEG code has signaled an error ! \n"));
302     WARNING (ErrMsg);
303 
304     jpeg_destroy_compress(&cinfo);
305     fclose(outfile);
306     return(FALSE);
307   }
308 
309   /* Now we can initialize the JPEG compression object. */
310   jpeg_create_compress(&cinfo);
311 
312   jpeg_stdio_dest(&cinfo, outfile);
313 
314   /* Step 3: set parameters for compression */
315 
316   /* First we supply a description of the input image.
317    * Four fields of the cinfo struct must be filled in:
318    */
319   cinfo.image_width = imgwidth;      /* image width and height, in pixels */
320   cinfo.image_height = imgheight;
321   cinfo.input_components = 3;           /* # of color components per pixel */
322   cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */
323 
324   /* Now use the library's routine to set default compression parameters.
325    * (You must set at least cinfo.in_color_space before calling this,
326    * since the defaults depend on the source color space.)
327    */
328   jpeg_set_defaults(&cinfo);
329   /* Now you can set any non-default parameters you wish to.
330    * Here we just illustrate the use of quality (quantization table) scaling:
331    */
332   jpeg_set_quality(&cinfo, quality, TRUE ); /* limit to baseline-JPEG values */
333 
334   /* Step 4: Start compressor */
335 
336   /* TRUE ensures that we will write a complete interchange-JPEG file.
337    * Pass TRUE unless you are very sure of what you're doing.
338    */
339   jpeg_start_compress(&cinfo, TRUE);
340 
341   /* Step 5: while (scan lines remain to be written) */
342   /*           jpeg_write_scanlines(...); */
343 
344   /* Here we use the library's state variable cinfo.next_scanline as the
345    * loop counter, so that we don't have to keep track ourselves.
346    * To keep things simple, we pass one scanline per call; you can pass
347    * more if you wish, though.
348    */
349   row_stride = imgwidth * 3; /* JSAMPLEs per row in imgbuff */
350   line = cinfo.image_height-1;
351   while (line >= 0) {
352     /* jpeg_write_scanlines expects an array of pointers to scanlines.
353      * Here the array is only one element long, but you could pass
354      * more than one scanline at a time if that's more convenient.
355      */
356     row_pointer[0] = & imgbuff[row_stride*line];
357     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
358     line--;
359   }
360 
361   /* Step 6: Finish compression */
362   jpeg_finish_compress(&cinfo);
363 
364   if (outfile) {
365     /* After finish_compress, we can close the output file. */
366     fclose(outfile);
367   }
368 
369   /* Step 7: release JPEG compression object */
370 
371   /* This is an important step since it will release a good deal of memory. */
372   jpeg_destroy_compress(&cinfo);
373   /* And we're done! */
374 
375   return(TRUE);
376 }
377 
378 float   texture_minval[NUM_COMP] = {0};
379 float   texture_maxval[NUM_COMP] = {0};
380 
381 #endif /* OpenGL end */
382