2 #include <lib/picviewer/format_config.h>
4 #include <lib/picviewer/pictureviewer.h>
13 Get a 2-byte integer, making no assumptions about CPU byte order.
14 Nor should we assume that the compiler evaluates left-to-right.
16 unsigned short fget2 (FILE *f
, int order
)
22 if (order
== 0x4949) /* "II" means little-endian */
24 else /* "MM" means big-endian */
29 Same for a 4-byte integer.
31 int fget4 (FILE *f
, int order
)
33 unsigned char a
, b
, c
, d
;
40 return a
+ (b
<< 8) + (c
<< 16) + (d
<< 24);
42 return (a
<< 24) + (b
<< 16) + (c
<< 8) + d
;
45 int fh_crw_parsedirs(FILE *fh
, int pos
, int length
, int order
)
47 fseek(fh
, pos
+ length
- 4, SEEK_SET
);
48 int off
= pos
+ fget4(fh
, order
);
49 fseek(fh
, off
, SEEK_SET
);
50 int nEntrys
= fget2(fh
, order
);
52 for (int i
= 0; i
< nEntrys
; i
++)
54 int type
= fget2(fh
, order
);
55 int len
= fget4(fh
, order
);
56 int roff
= fget4(fh
, order
);
62 case 0x2007: // Thumbnail
63 fseek(fh
, pos
+ roff
, SEEK_SET
);
68 case 0x0816: // Filename
70 case 0x0817: // Thumbname
72 case 0x580b: // SerNo.
74 case 0x0805: // comment, if subdir 0x300a. "EOS 300D DIGITAL CMOS RAW" if subdir 0x2804
76 case 0x080a: // vendor \0 name of the camera
78 case 0x080b: // firmware
84 case 0x102a: // White balance
86 case 0x1031: // size of the image
88 case 0x1835: // decoder table
91 if (type
>> 8 == 0x28 || type
>> 8 == 0x30) // Subdirs
93 if (fh_crw_parsedirs(fh
, pos
+ roff
, len
, order
) == 1)
103 void fh_crw_find_jpeg_thumbnail(FILE *fh
)
110 fseek (fh
, 0, SEEK_SET
);
111 fread (header
, 1, 26, fh
);
112 fseek (fh
, 0, SEEK_END
);
114 fseek (fh
, 0, SEEK_SET
);
116 order
= *((unsigned short *)header
);
119 hlength
= header
[2] + (header
[3] << 8) + (header
[4] << 16) + (header
[5] << 24);
121 hlength
= (header
[2] << 24) + (header
[3] << 16) + (header
[4] << 8) + header
[5];
123 fh_crw_parsedirs(fh
, hlength
, fsize
- hlength
, order
);
126 struct r_crw_jpeg_error_mgr
128 struct jpeg_error_mgr pub
;
132 int fh_crw_id(const char *name
)
134 // dbout("fh_crw_id {\n");
136 unsigned char id
[14];
137 fd
= open(name
, O_RDONLY
);
142 // dbout("fh_crw_id }\n");
143 if (id
[6] == 'H' && id
[7] == 'E' && id
[8] == 'A' && id
[9] == 'P' &&
144 id
[10] == 'C' && id
[11] == 'C' && id
[12] == 'D' && id
[13] == 'R')
151 void crw_cb_error_exit(j_common_ptr cinfo
)
153 // dbout("crw_cb_error_exit {\n");
154 struct r_crw_jpeg_error_mgr
*mptr
;
155 mptr
= (struct r_crw_jpeg_error_mgr
*) cinfo
->err
;
156 (*cinfo
->err
->output_message
) (cinfo
);
157 longjmp(mptr
->envbuffer
, 1);
158 // dbout("crw_cb_error_exit }\n");
161 int fh_crw_load(const char *filename
, unsigned char *buffer
, int x
, int y
)
163 // dbout("fh_crw_load (%d/%d) {\n",x,y);
164 struct jpeg_decompress_struct cinfo
;
165 struct jpeg_decompress_struct
*ciptr
;
166 struct r_crw_jpeg_error_mgr emgr
;
173 if (!(fh
= fopen(filename
, "rb")))
174 return(FH_ERROR_FILE
);
175 ciptr
->err
= jpeg_std_error(&emgr
.pub
);
176 emgr
.pub
.error_exit
= crw_cb_error_exit
;
177 if (setjmp(emgr
.envbuffer
) == 1)
179 // FATAL ERROR - Free the object and return...
180 jpeg_destroy_decompress(ciptr
);
182 // dbout("fh_crw_load } - FATAL ERROR\n");
183 return(FH_ERROR_FORMAT
);
186 jpeg_create_decompress(ciptr
);
187 fh_crw_find_jpeg_thumbnail(fh
);
188 jpeg_stdio_src(ciptr
, fh
);
189 jpeg_read_header(ciptr
, TRUE
);
190 ciptr
->out_color_space
= JCS_RGB
;
191 if (x
== (int)ciptr
->image_width
)
192 ciptr
->scale_denom
= 1;
194 if (abs(x
* 2 - ciptr
->image_width
) < 2)
195 ciptr
->scale_denom
= 2;
197 if (abs(x
* 4 - ciptr
->image_width
) < 4)
198 ciptr
->scale_denom
= 4;
200 if (abs(x
* 8 - ciptr
->image_width
) < 8)
201 ciptr
->scale_denom
= 8;
203 ciptr
->scale_denom
= 1;
205 jpeg_start_decompress(ciptr
);
207 px
= ciptr
->output_width
; py
= ciptr
->output_height
;
208 c
= ciptr
->output_components
;
212 lb
= (JSAMPLE
*)(*ciptr
->mem
->alloc_small
)((j_common_ptr
) ciptr
, JPOOL_PERMANENT
, c
* px
);
214 while (ciptr
->output_scanline
< ciptr
->output_height
)
216 jpeg_read_scanlines(ciptr
, &lb
, 1);
217 memcpy(bp
, lb
, px
* c
);
221 jpeg_finish_decompress(ciptr
);
222 jpeg_destroy_decompress(ciptr
);
224 // dbout("fh_crw_load }\n");
228 int fh_crw_getsize(const char *filename
, int *x
, int *y
, int wanted_width
, int wanted_height
)
230 // dbout("fh_crw_getsize {\n");
231 struct jpeg_decompress_struct cinfo
;
232 struct jpeg_decompress_struct
*ciptr
;
233 struct r_crw_jpeg_error_mgr emgr
;
239 if (!(fh
= fopen(filename
, "rb")))
240 return(FH_ERROR_FILE
);
242 ciptr
->err
= jpeg_std_error(&emgr
.pub
);
243 emgr
.pub
.error_exit
= crw_cb_error_exit
;
244 if (setjmp(emgr
.envbuffer
) == 1)
246 // FATAL ERROR - Free the object and return...
247 jpeg_destroy_decompress(ciptr
);
249 // dbout("fh_crw_getsize } - FATAL ERROR\n");
250 return(FH_ERROR_FORMAT
);
253 jpeg_create_decompress(ciptr
);
254 fh_crw_find_jpeg_thumbnail(fh
);
255 jpeg_stdio_src(ciptr
, fh
);
256 jpeg_read_header(ciptr
, TRUE
);
257 ciptr
->out_color_space
= JCS_RGB
;
258 // should be more flexible...
259 if ((int)ciptr
->image_width
/ 8 >= wanted_width
||
260 (int)ciptr
->image_height
/ 8 >= wanted_height
)
261 ciptr
->scale_denom
= 8;
263 if ((int)ciptr
->image_width
/ 4 >= wanted_width
||
264 (int)ciptr
->image_height
/ 4 >= wanted_height
)
265 ciptr
->scale_denom
= 4;
267 if ((int)ciptr
->image_width
/ 2 >= wanted_width
||
268 (int)ciptr
->image_height
/ 2 >= wanted_height
)
269 ciptr
->scale_denom
= 2;
271 ciptr
->scale_denom
= 1;
273 jpeg_start_decompress(ciptr
);
274 px
= ciptr
->output_width
; py
= ciptr
->output_height
;
275 c
= ciptr
->output_components
;
277 // jpeg_finish_decompress(ciptr);
278 jpeg_destroy_decompress(ciptr
);
280 // dbout("fh_crw_getsize }\n");