Imported PTViewer 0.4 as received from <http://www.all-in-one.ee/~dersch/>.
[libopano.git] / src / jpeg.c
1 /* Panorama_Tools       -       Generate, Edit and Convert Panoramic Images
2    Copyright (C) 1998,1999 - Helmut Dersch  der@fh-furtwangen.de
3    
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 /*------------------------------------------------------------*/
19
20 #include <stdio.h>
21 #include "jpeglib.h"
22 #include "filter.h"
23
24
25
26
27 int writeJPEG( Image *im, fullPath *sfile,      int quality, int progressive )
28 {
29         struct jpeg_compress_struct cinfo;
30         struct jpeg_error_mgr jerr;
31         FILE * outfile;
32         char filename[512];
33         int scanlines_written;
34         unsigned char *data,*buf;
35         
36         cinfo.err = jpeg_std_error(&jerr);
37         jpeg_create_compress(&cinfo);
38
39 //      if( GetFullPath (sfile, filename))
40 //              return -1;
41         strcpy(filename, sfile->name);
42         if ((outfile = fopen(filename, "wb")) == NULL) 
43         {
44             PrintError("can't open %s", filename);
45             return -1;
46         }
47 //      TwoToOneByte( im );
48         
49         jpeg_stdio_dest(&cinfo, outfile);
50         
51         
52
53         cinfo.image_width               = im->width;    /* image width and height, in pixels */
54         cinfo.image_height              = im->height;
55         cinfo.input_components  = 3;    /* # of color components per pixel */
56         cinfo.in_color_space    = JCS_RGB; /* colorspace of input image */
57
58         jpeg_set_defaults(&cinfo);
59
60         jpeg_set_quality (&cinfo, quality, TRUE);
61         
62         if( progressive )
63                 jpeg_simple_progression (&cinfo);
64
65         
66         jpeg_start_compress(&cinfo, TRUE);
67         
68         scanlines_written = 0;
69         data = *(im->data);
70         buf = (unsigned char*)malloc( im->bytesPerLine );
71         if(buf == NULL)         
72         {
73         
74             PrintError("Not enough memory");
75                 fclose( outfile );
76             return -1;
77         }
78
79
80         while ( scanlines_written < im->height ) 
81         {
82                 memcpy(buf, data, im->bytesPerLine );
83                 if( im->bitsPerPixel == 32 )    // Convert 4->3 samples
84                 {
85                         int x;
86                         unsigned char *c1=buf, *c2=buf;
87                         for(x=0; x < im->width; x++)
88                         {
89                                 c2++;
90                                 *c1++ = *c2++;
91                                 *c1++ = *c2++;
92                                 *c1++ = *c2++;
93                         }
94                                 
95                 }       
96                 
97             if( jpeg_write_scanlines(&cinfo, (JSAMPARRAY) &buf, 1) )
98                 {
99                         scanlines_written++;
100                         data += im->bytesPerLine;
101                 }
102         }
103         jpeg_finish_compress(&cinfo);
104         jpeg_destroy_compress(&cinfo);
105         fclose( outfile );
106         free( buf );
107         return 0;
108         
109
110 }
111
112
113
114 int readJPEG ( Image *im, fullPath *sfile )
115 {
116         struct jpeg_decompress_struct cinfo;
117         struct jpeg_error_mgr jerr;
118         FILE * infile;
119         char filename[256];
120         int scan_lines_to_be_read, i, scanheight, scan_lines_read;
121         unsigned char*data;
122         JSAMPARRAY sarray;
123
124         //PrintError("%s", sfile->name);        
125
126         cinfo.err = jpeg_std_error(&jerr);
127         jpeg_create_decompress(&cinfo);
128
129
130 //      if( GetFullPath (sfile, filename))
131 //              return -1;
132
133         strcpy(filename, sfile->name);
134         if ((infile = fopen(filename, "rb")) == NULL) 
135         {
136             PrintError("can't open %s", filename);
137             return -1;
138         }
139
140         jpeg_stdio_src(&cinfo, infile);
141
142         jpeg_read_header(&cinfo, TRUE);
143
144         jpeg_start_decompress(&cinfo);
145
146         SetImageDefaults( im );
147         im->width =     cinfo.output_width;
148         im->height =    cinfo.output_height;
149         if( cinfo.output_components != 3 )
150         {
151                 PrintError("Image must be rgb");
152                 fclose( infile );
153                 return -1;
154         }
155         
156
157         im->bitsPerPixel = 24;
158         im->bytesPerLine = im->width*3  ;
159         //im->bytesPerLine  *= 12;
160         im->dataSize = im->width * 4 * im->height;
161         im->data = (unsigned char**)mymalloc( im->dataSize );
162         if( im->data == NULL )
163         {
164                 PrintError("Not enough memory");
165                 fclose( infile );
166                 return -1;
167         }
168         
169         scanheight = cinfo.rec_outbuf_height;
170         sarray = (JSAMPARRAY) malloc( scanheight * sizeof( JSAMPROW ) );
171         
172         scan_lines_to_be_read = im->height;
173         data = *(im->data);
174         
175          while (scan_lines_to_be_read)
176          {
177                 for(i=0; i<scanheight; i++)
178                 {
179                         sarray[i] = (JSAMPROW) (data + i*im->bytesPerLine);
180                 }
181                 
182                 scan_lines_read = jpeg_read_scanlines(&cinfo, sarray, scanheight);
183                 
184                 scan_lines_to_be_read -= scan_lines_read;
185                 data += scan_lines_read * im->bytesPerLine;
186         }
187         jpeg_finish_decompress(&cinfo);
188         jpeg_destroy_decompress(&cinfo);
189         
190         ThreeToFourBPP( im );
191         free( sarray );
192         
193         fclose( infile );
194
195         return 0;
196
197
198 }
199