1 #include <stdio.h>
2 //#include <jpeglib.h>
3 //#define __NO_SYSTEM__
4 #include "filter.h"
5 #include "metadata.h"
6 #include "file.h"
7 
8 #include "jpegicc.h"
9 
10 
writeJPEG(Image * im,fullPath * sfile,int quality,int progressive)11 int writeJPEG(Image * im, fullPath * sfile, int quality, int progressive)
12 {
13     struct jpeg_compress_struct cinfo;
14     struct jpeg_error_mgr jerr;
15     FILE *outfile;
16     char filename[512];
17     int scanlines_written;
18     unsigned char *data, *buf;
19 
20 #ifdef __Mac__
21     unsigned char the_pcUnixFilePath[512];      // added by Kekus Digital
22     Str255 the_cString;
23     Boolean the_bReturnValue;
24     CFStringRef the_FilePath;
25     CFURLRef the_Url;           //till here
26 #endif
27 
28     cinfo.err = jpeg_std_error(&jerr);
29     jpeg_create_compress(&cinfo);
30 
31     if (GetFullPath(sfile, filename))
32         return -1;
33 
34 #ifdef __Mac__
35     CopyCStringToPascal(filename, the_cString); //Added by Kekus Digital
36     the_FilePath =
37         CFStringCreateWithPascalString(kCFAllocatorDefault, the_cString,
38                                        kCFStringEncodingUTF8);
39     the_Url =
40         CFURLCreateWithFileSystemPath(kCFAllocatorDefault, the_FilePath,
41                                       kCFURLHFSPathStyle, false);
42     the_bReturnValue =
43         CFURLGetFileSystemRepresentation(the_Url, true, the_pcUnixFilePath,
44                                          512);
45 
46     strcpy(filename, the_pcUnixFilePath);       //till here
47 #endif
48 
49     if ((outfile = fopen(filename, "wb")) == NULL)
50     {
51         PrintError("can't open %s", filename);
52         return -1;
53     }
54     TwoToOneByte(im);
55 
56     jpeg_stdio_dest(&cinfo, outfile);
57 
58 
59 
60     cinfo.image_width = im->width;      /* image width and height, in pixels */
61     cinfo.image_height = im->height;
62     cinfo.input_components = 3; /* # of color components per pixel */
63     cinfo.in_color_space = JCS_RGB;     /* colorspace of input image */
64 
65     jpeg_set_defaults(&cinfo);
66 
67     if (2 != (progressive & 2))
68         cinfo.optimize_coding = TRUE;
69 
70     jpeg_set_quality(&cinfo, quality, TRUE);
71 
72     if (1 == (progressive & 1))
73         jpeg_simple_progression(&cinfo);
74 
75 
76     jpeg_start_compress(&cinfo, TRUE);
77 
78     // Write ICC Profile if it exists
79 
80     if (im->metadata.iccProfile.size > 0) {
81         jpegICCWriteProfile(&cinfo,
82                            (JOCTET *)im->metadata.iccProfile.data,
83                            im->metadata.iccProfile.size);
84     }
85 
86     scanlines_written = 0;
87     data = *(im->data);
88     buf = (unsigned char *) malloc((size_t) im->bytesPerLine);
89     if (buf == NULL)
90     {
91 
92         PrintError("Not enough memory");
93         fclose(outfile);
94         return -1;
95     }
96 
97 
98     while (scanlines_written < im->height)
99     {
100         memcpy(buf, data, (size_t) im->bytesPerLine);
101         if (im->bitsPerPixel == 32)     // Convert 4->3 samples
102         {
103             int x;
104             unsigned char *c1 = buf, *c2 = buf;
105             for (x = 0; x < im->width; x++)
106             {
107                 c2++;
108                 *c1++ = *c2++;
109                 *c1++ = *c2++;
110                 *c1++ = *c2++;
111             }
112 
113         }
114 
115         if (jpeg_write_scanlines(&cinfo, (JSAMPARRAY) & buf, 1))
116         {
117             scanlines_written++;
118             data += im->bytesPerLine;
119         }
120     }
121     jpeg_finish_compress(&cinfo);
122     jpeg_destroy_compress(&cinfo);
123     fclose(outfile);
124     free(buf);
125     return 0;
126 
127 
128 }
129 
130 
readJPEG(Image * im,fullPath * sfile)131 int readJPEG(Image * im, fullPath * sfile)
132 {
133     struct jpeg_decompress_struct cinfo;
134     struct jpeg_error_mgr jerr;
135     FILE *infile;
136     char filename[256];
137     int scan_lines_to_be_read, scan_lines_read;
138     unsigned int i, scanheight;
139     unsigned char *data;
140     JSAMPARRAY sarray;
141     JOCTET *ptr = NULL;
142     unsigned int size  = 0;
143 
144 
145 
146 #ifdef __Mac__
147     unsigned char the_pcUnixFilePath[256];      // added by Kekus Digital
148     Str255 the_cString;
149     Boolean the_bReturnValue;
150     CFStringRef the_FilePath;
151     CFURLRef the_Url;           //till here
152 #endif
153 
154     //PrintError("%s", sfile->name);
155 
156     cinfo.err = jpeg_std_error(&jerr);
157     jpeg_create_decompress(&cinfo);
158 
159     // Prepare the library for reading the ICC profile, see its source code
160     // for further information
161     jpegICCSetupReadICCProfile(&cinfo);
162 
163     if (GetFullPath(sfile, filename))
164         return -1;
165 
166 #ifdef __Mac__
167     CopyCStringToPascal(filename, the_cString); //Added by Kekus Digital
168     the_FilePath =
169         CFStringCreateWithPascalString(kCFAllocatorDefault, the_cString,
170                                        kCFStringEncodingUTF8);
171     the_Url =
172         CFURLCreateWithFileSystemPath(kCFAllocatorDefault, the_FilePath,
173                                       kCFURLHFSPathStyle, false);
174     the_bReturnValue =
175         CFURLGetFileSystemRepresentation(the_Url, true, the_pcUnixFilePath,
176                                          256);
177 
178     strcpy(filename, the_pcUnixFilePath);       //till here
179 #endif
180 
181     if ((infile = fopen(filename, "rb")) == NULL) {
182         PrintError("can't open %s", filename);
183         return -1;
184     }
185 
186     jpeg_stdio_src(&cinfo, infile);
187 
188     jpeg_read_header(&cinfo, TRUE);
189 
190     jpeg_start_decompress(&cinfo);
191 
192     SetImageDefaults(im);
193     im->width = cinfo.output_width;
194     im->height = cinfo.output_height;
195     if (cinfo.output_components != 3)
196     {
197         PrintError("Image must be rgb");
198         fclose(infile);
199         return -1;
200     }
201 
202 
203     im->bitsPerPixel = 24;
204     im->bytesPerLine = im->width * 3;
205     im->dataSize = im->width * 4 * im->height;
206     im->data = (unsigned char **) mymalloc((size_t) im->dataSize);
207     if (im->data == NULL)
208     {
209         PrintError("Not enough memory");
210         fclose(infile);
211         return -1;
212     }
213 
214     scanheight = cinfo.rec_outbuf_height;
215     sarray = (JSAMPARRAY) malloc(scanheight * sizeof(JSAMPROW));
216 
217     scan_lines_to_be_read = im->height;
218     data = *(im->data);
219 
220     while (scan_lines_to_be_read)
221     {
222         for (i = 0; i < scanheight; i++)
223         {
224             sarray[i] = (JSAMPROW) (data + i * im->bytesPerLine);
225         }
226 
227         scan_lines_read = jpeg_read_scanlines(&cinfo, sarray, scanheight);
228 
229         scan_lines_to_be_read -= scan_lines_read;
230         data += scan_lines_read * im->bytesPerLine;
231     }
232 
233     // read ICC profile
234 
235     if (jpegICCReadProfile(&cinfo, &ptr, &size)) {
236 
237         im->metadata.iccProfile.size = size;
238         im->metadata.iccProfile.data = (char*) ptr;
239     }
240 
241     jpeg_finish_decompress(&cinfo);
242     jpeg_destroy_decompress(&cinfo);
243 
244     ThreeToFourBPP(im);
245     free(sarray);
246 
247 
248     fclose(infile);
249 
250     return 0;
251 
252 
253 }
254 
255 // this function is very likely to change
256 // so it should be considered a hack until
257 // we are able to read all the JPEG metadata
258 
panoJPEGRead(Image * im,fullPath * sfile)259 int panoJPEGRead(Image * im, fullPath * sfile)
260 {
261   if ( readJPEG(im, sfile) == 0) {
262       return panoMetadataUpdateFromImage(im);
263   } else
264       return FALSE;
265 
266 
267 }
268