update internal LibRaw to official 0.7.0 release...
[kdegraphics.git] / libs / libkdcraw / libraw / src / libraw_cxx.cpp
blob5a6e020f9a088083bf5be719cc47b053c457ea25
1 /* -*- C++ -*-
2 * File: libraw_cxx.cpp
3 * Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
4 * Created: Sat Mar 8 , 2008
6 * LibRaw C++ interface (implementation)
7 */
9 #include <errno.h>
10 #include <float.h>
11 #include <math.h>
12 #ifndef WIN32
13 #include <netinet/in.h>
14 #else
15 #include <winsock2.h>
16 #endif
17 #define LIBRAW_LIBRARY_BUILD
18 #include "libraw/libraw.h"
20 #ifdef __cplusplus
21 extern "C"
23 #endif
24 void default_memory_callback(void *,const char *file,const char *where)
26 fprintf (stderr,"%s: Out of memory in %s\n", file?file:"unknown file", where);
29 void default_data_callback(void*,const char *file, const int offset)
31 if(offset < 0)
32 fprintf (stderr,"%s: Unexpected end of file\n", file?file:"unknown file");
33 else
34 fprintf (stderr,"%s: data corrupted at %d\n",file?file:"unknown file",offset);
36 const char *libraw_strerror(int e)
38 enum LibRaw_errors errorcode = (LibRaw_errors)e;
39 switch(errorcode)
41 case LIBRAW_SUCCESS:
42 return "No error";
43 case LIBRAW_UNSPECIFIED_ERROR:
44 return "Unspecified error";
45 case LIBRAW_FILE_UNSUPPORTED:
46 return "Unsupported file format or not RAW file";
47 case LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE:
48 return "Request for nonexisting image number";
49 case LIBRAW_OUT_OF_ORDER_CALL:
50 return "Out of order call of libraw function";
51 case LIBRAW_NO_THUMBNAIL:
52 return "No thumbnail in file";
53 case LIBRAW_UNSUPPORTED_THUMBNAIL:
54 return "Unsupported thumbnail format";
55 case LIBRAW_CANNOT_ADDMASK:
56 return "Cannot add masked pixels to resized image";
57 case LIBRAW_UNSUFFICIENT_MEMORY:
58 return "Unsufficient memory";
59 case LIBRAW_DATA_ERROR:
60 return "Corrupted data or unexpected EOF";
61 case LIBRAW_IO_ERROR:
62 return "Input/output error";
63 case LIBRAW_CANCELLED_BY_CALLBACK:
64 return "Cancelled by user callback";
65 default:
66 return "Unknown error code";
70 #ifdef __cplusplus
72 #endif
75 const double LibRaw_constants::xyz_rgb[3][3] =
77 { 0.412453, 0.357580, 0.180423 },
78 { 0.212671, 0.715160, 0.072169 },
79 { 0.019334, 0.119193, 0.950227 }
82 const float LibRaw_constants::d65_white[3] = { 0.950456, 1, 1.088754 };
84 #define P1 imgdata.idata
85 #define S imgdata.sizes
86 #define O imgdata.params
87 #define C imgdata.color
88 #define M imgdata.masked_pixels
89 #define T imgdata.thumbnail
90 #define IO libraw_internal_data.internal_output_params
91 #define ID libraw_internal_data.internal_data
93 #define EXCEPTION_HANDLER(e) do{ \
94 fprintf(stderr,"Exception %d caught\n",e); \
95 switch(e) \
96 { \
97 case LIBRAW_EXCEPTION_ALLOC: \
98 recycle(); \
99 return LIBRAW_UNSUFFICIENT_MEMORY; \
100 case LIBRAW_EXCEPTION_DECODE_RAW: \
101 case LIBRAW_EXCEPTION_DECODE_JPEG: \
102 recycle(); \
103 return LIBRAW_DATA_ERROR; \
104 case LIBRAW_EXCEPTION_IO_EOF: \
105 case LIBRAW_EXCEPTION_IO_CORRUPT: \
106 recycle(); \
107 return LIBRAW_IO_ERROR; \
108 case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK:\
109 recycle(); \
110 return LIBRAW_CANCELLED_BY_CALLBACK; \
111 default: \
112 return LIBRAW_UNSPECIFIED_ERROR; \
114 }while(0)
116 void LibRaw::derror()
118 if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input)
120 if (libraw_internal_data.internal_data.input->eof())
122 if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
123 libraw_internal_data.internal_data.input->fname(),-1);
124 throw LIBRAW_EXCEPTION_IO_EOF;
126 else
128 if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
129 libraw_internal_data.internal_data.input->fname(),
130 libraw_internal_data.internal_data.input->tell());
131 throw LIBRAW_EXCEPTION_IO_CORRUPT;
134 libraw_internal_data.unpacker_data.data_error = 1;
136 LibRaw:: LibRaw(unsigned int flags)
138 double aber[4] = {1,1,1,1};
139 double gamm[5] = { 0.45,4.5,0,0,0 };
140 unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
141 #ifdef DCRAW_VERBOSE
142 verbose = 1;
143 #else
144 verbose = 0;
145 #endif
146 bzero(&imgdata,sizeof(imgdata));
147 bzero(&libraw_internal_data,sizeof(libraw_internal_data));
148 bzero(&callbacks,sizeof(callbacks));
149 callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL: &default_memory_callback;
150 callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
151 memmove(&imgdata.params.aber,&aber,sizeof(aber));
152 memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
153 memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
155 imgdata.params.bright=1;
156 imgdata.params.use_camera_matrix=-1;
157 imgdata.params.user_flip=-1;
158 imgdata.params.user_black=-1;
159 imgdata.params.user_sat=-1;
160 imgdata.params.user_qual=-1;
161 imgdata.params.output_color=1;
162 imgdata.params.output_bps=8;
163 imgdata.params.use_fuji_rotate=1;
164 imgdata.parent_class = this;
165 imgdata.progress_flags = 0;
166 tls = new LibRaw_TLS;
167 tls->init();
171 void* LibRaw:: malloc(size_t t)
173 void *p = memmgr.malloc(t);
174 return p;
176 void* LibRaw:: calloc(size_t n,size_t t)
178 void *p = memmgr.calloc(n,t);
179 return p;
181 void LibRaw:: free(void *p)
183 memmgr.free(p);
187 int LibRaw:: fc (int row, int col)
189 static const char filter[16][16] =
190 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
191 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
192 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
193 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
194 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
195 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
196 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
197 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
198 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
199 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
200 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
201 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
202 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
203 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
204 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
205 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
207 if (imgdata.idata.filters != 1) return FC(row,col);
208 return filter[(row+imgdata.sizes.top_margin) & 15][(col+imgdata.sizes.left_margin) & 15];
211 void LibRaw:: recycle()
213 if(libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal)
215 delete libraw_internal_data.internal_data.input;
216 libraw_internal_data.internal_data.input = NULL;
218 libraw_internal_data.internal_data.input_internal = 0;
219 #define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
221 FREE(imgdata.image);
222 FREE(imgdata.thumbnail.thumb);
223 FREE(libraw_internal_data.internal_data.meta_data);
224 FREE(libraw_internal_data.output_data.histogram);
225 FREE(libraw_internal_data.output_data.oprof);
226 FREE(imgdata.color.profile);
227 FREE(imgdata.masked_pixels.buffer);
228 FREE(imgdata.masked_pixels.ph1_black);
229 #undef FREE
230 #define ZERO(a) bzero(&a,sizeof(a))
231 ZERO(imgdata.masked_pixels);
232 ZERO(imgdata.sizes);
233 ZERO(libraw_internal_data.internal_output_params);
234 #undef ZERO
235 memmgr.cleanup();
236 imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
237 imgdata.progress_flags = 0;
239 tls->init();
242 const char * LibRaw::unpack_function_name()
244 if(!load_raw) return "Function not set";
246 // sorted names order
247 if (load_raw == &LibRaw::adobe_dng_load_raw_lj) return "adobe_dng_load_raw_lj()";
248 if (load_raw == &LibRaw::adobe_dng_load_raw_nc) return "adobe_dng_load_raw_nc()";
249 if (load_raw == &LibRaw::canon_600_load_raw) return "canon_600_load_raw()";
251 if (load_raw == &LibRaw::canon_a5_load_raw) return "canon_a5_load_raw()";
252 if (load_raw == &LibRaw::canon_compressed_load_raw) return "canon_compressed_load_raw()";
253 if (load_raw == &LibRaw::canon_sraw_load_raw) return "canon_sraw_load_raw()";
255 if (load_raw == &LibRaw::casio_qv5700_load_raw ) return "casio_qv5700_load_raw()";
256 if (load_raw == &LibRaw::eight_bit_load_raw ) return "eight_bit_load_raw()";
257 if (load_raw == &LibRaw::foveon_load_raw ) return "foveon_load_raw()";
258 if (load_raw == &LibRaw::fuji_load_raw ) return "fuji_load_raw()";
259 // 10
260 if (load_raw == &LibRaw::hasselblad_load_raw ) return "hasselblad_load_raw()";
261 if (load_raw == &LibRaw::imacon_full_load_raw ) return "imacon_full_load_raw()";
262 if (load_raw == &LibRaw::kodak_262_load_raw ) return "kodak_262_load_raw()";
264 if (load_raw == &LibRaw::kodak_65000_load_raw ) return "kodak_65000_load_raw()";
265 if (load_raw == &LibRaw::kodak_dc120_load_raw ) return "kodak_dc120_load_raw()";
266 if (load_raw == &LibRaw::kodak_jpeg_load_raw ) return "kodak_jpeg_load_raw()";
268 if (load_raw == &LibRaw::kodak_radc_load_raw ) return "kodak_radc_load_raw()";
269 if (load_raw == &LibRaw::kodak_rgb_load_raw ) return "kodak_rgb_load_raw()";
270 if (load_raw == &LibRaw::kodak_yrgb_load_raw ) return "kodak_yrgb_load_raw()";
271 if (load_raw == &LibRaw::kodak_ycbcr_load_raw ) return "kodak_ycbcr_load_raw()";
272 // 20
273 if (load_raw == &LibRaw::leaf_hdr_load_raw ) return "leaf_hdr_load_raw()";
274 if (load_raw == &LibRaw::lossless_jpeg_load_raw) return "lossless_jpeg_load_raw()";
275 if (load_raw == &LibRaw::minolta_rd175_load_raw ) return "minolta_rd175_load_raw()";
277 if (load_raw == &LibRaw::nikon_compressed_load_raw) return "nikon_compressed_load_raw()";
278 if (load_raw == &LibRaw::nikon_e900_load_raw ) return "nikon_e900_load_raw()";
279 if (load_raw == &LibRaw::nokia_load_raw ) return "nokia_load_raw()";
281 if (load_raw == &LibRaw::olympus_e300_load_raw ) return "olympus_e300_load_raw()";
282 if (load_raw == &LibRaw::olympus_e410_load_raw ) return "olympus_e410_load_raw()";
283 if (load_raw == &LibRaw::packed_12_load_raw ) return "packed_12_load_raw()";
284 if (load_raw == &LibRaw::panasonic_load_raw ) return "panasonic_load_raw()";
285 // 30
286 if (load_raw == &LibRaw::pentax_k10_load_raw ) return "pentax_k10_load_raw()";
287 if (load_raw == &LibRaw::phase_one_load_raw ) return "phase_one_load_raw()";
288 if (load_raw == &LibRaw::phase_one_load_raw_c ) return "phase_one_load_raw_c()";
290 if (load_raw == &LibRaw::quicktake_100_load_raw ) return "quicktake_100_load_raw()";
291 if (load_raw == &LibRaw::rollei_load_raw ) return "rollei_load_raw()";
292 if (load_raw == &LibRaw::sinar_4shot_load_raw ) return "sinar_4shot_load_raw()";
294 if (load_raw == &LibRaw::smal_v6_load_raw ) return "smal_v6_load_raw()";
295 if (load_raw == &LibRaw::smal_v9_load_raw ) return "smal_v9_load_raw()";
296 if (load_raw == &LibRaw::sony_load_raw ) return "sony_load_raw()";
297 if (load_raw == &LibRaw::sony_arw_load_raw ) return "sony_arw_load_raw()";
298 // 40
299 if (load_raw == &LibRaw::sony_arw2_load_raw ) return "sony_arw2_load_raw()";
300 if (load_raw == &LibRaw::unpacked_load_raw ) return "unpacked_load_raw()";
301 // 42 total
303 return "Unknown unpack function";
307 void LibRaw:: merror (void *ptr, const char *where)
309 if (ptr) return;
310 if(callbacks.mem_cb)(*callbacks.mem_cb)(callbacks.memcb_data,
311 libraw_internal_data.internal_data.input
312 ?libraw_internal_data.internal_data.input->fname()
313 :NULL,
314 where);
315 throw LIBRAW_EXCEPTION_ALLOC;
318 ushort * LibRaw::get_masked_pointer(int row, int col)
320 if(row<0 || col < 0) return NULL;
321 if(!M.buffer) return NULL;
322 if(row < S.top_margin)
324 // top band
325 if(col < S.left_margin)
327 return &(M.tl[row*S.left_margin+col]);
329 else if (col < S.left_margin + S.width)
331 int icol = col - S.left_margin;
332 return &(M.top[row*S.width+icol]);
334 else if (col < S.raw_width)
336 int icol = col - S.left_margin - S.width;
337 return &(M.tr[row*S.right_margin+icol]);
339 else
340 return NULL; // out of bounds
342 else if (row < S.top_margin + S.height)
344 //normal image height
345 int irow = row - S.top_margin;
346 if(col < S.left_margin)
348 return &M.left[irow*S.left_margin + col];
350 else if (col < S.left_margin + S.width)
352 // central image
353 return NULL;
355 else if (col < S.raw_width)
357 int icol = col - S.left_margin - S.width;
358 return &M.right[irow*S.right_margin+icol];
360 else
361 return NULL; // out of bounds
363 else if (row < S.raw_height)
365 int irow = row - S.top_margin - S.height;
366 // bottom band
367 if(col < S.left_margin)
369 return &M.bl[irow*S.left_margin+col];
371 else if (col < S.left_margin + S.width)
373 int icol = col - S.left_margin;
374 return &M.bottom[irow*S.width + icol];
376 else if (col < S.raw_width)
378 int icol = col - S.left_margin - S.width;
379 return &M.br[irow*S.right_margin + icol];
381 else
382 return NULL; // out of bounds
384 else
386 // out of bounds
387 return NULL;
389 // fallback
390 return NULL;
393 void LibRaw:: init_masked_ptrs()
395 if(!M.buffer) return;
397 // top band
398 M.tl = M.buffer;
399 M.top = M.tl +(S.top_margin*S.left_margin);
400 M.tr = M.top + (S.top_margin*S.width);
402 // left-right
403 M.left = M.tr + (S.top_margin * S.right_margin);
404 M.right = M.left + (S.left_margin * S.height);
406 // bottom band
407 M.bl = M.right + (S.right_margin * S.height);
408 M.bottom = M.bl + (S.left_margin * S.bottom_margin);
409 M.br = M.bottom + (S.width * S.bottom_margin);
413 int LibRaw::add_masked_borders_to_bitmap()
415 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
416 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
418 if(S.width != S.iwidth || S.height!=S.iheight)
419 return LIBRAW_CANNOT_ADDMASK;
421 if(P1.is_foveon || !P1.filters)
422 return LIBRAW_CANNOT_ADDMASK;
424 if(!imgdata.image)
425 return LIBRAW_OUT_OF_ORDER_CALL;
427 if(S.raw_width < S.width || S.raw_height < S.height)
428 return LIBRAW_SUCCESS; // nothing to do or already called
430 if(S.width == S.raw_width && S.height == S.raw_height)
431 return LIBRAW_SUCCESS; // nothing to do or already called
433 ushort (*newimage)[4];
435 newimage = (ushort (*)[4]) calloc (S.raw_height*S.raw_width, sizeof (*newimage));
436 merror (newimage, "add_masked_borders_to_bitmap()");
438 int r,c;
439 // top rows
440 for (r=0; r<S.top_margin;r++)
441 for(c=0;c<S.raw_width;c++)
443 ushort *p = get_masked_pointer(r,c);
444 if(p)
445 newimage[r*S.raw_width+c][FC(r,c)] = *p;
447 // middle rows
448 for (r=S.top_margin; r<S.top_margin+S.height;r++)
450 int row = r-S.top_margin;
451 for(c=0;c<S.left_margin;c++)
453 ushort *p = get_masked_pointer(r,c);
454 if(p)
455 newimage[r*S.raw_width+c][FC(r,c)] = *p;
457 for(c=S.left_margin; c<S.left_margin+S.iwidth;c++)
459 int col = c - S.left_margin;
460 newimage[r*S.raw_width+c][FC(r,c)] = imgdata.image[row*S.iwidth+col][FC(row,col)];
462 for(c=S.left_margin+S.iwidth;c<S.raw_width;c++)
464 ushort *p = get_masked_pointer(r,c);
465 if(p)
466 newimage[r*S.raw_width+c][FC(r,c)] = *p;
469 // bottom rows
470 for (r=S.top_margin+S.height; r<S.raw_height;r++)
471 for(c=0;c<S.raw_width;c++)
473 ushort *p = get_masked_pointer(r,c);
474 if(p)
475 newimage[r*S.raw_width+c][FC(r,c)] = *p;
477 free(imgdata.image);
478 imgdata.image=newimage;
479 S.iwidth = S.width = S.raw_width;
480 S.iheight = S.height = S.raw_height;
481 return LIBRAW_SUCCESS;
484 int LibRaw::open_file(const char *fname)
486 // this stream will close on recycle()
487 LibRaw_file_datastream *stream = new LibRaw_file_datastream(fname);
488 if(!stream->valid())
490 delete stream;
491 return LIBRAW_IO_ERROR;
493 ID.input_internal = 0; // preserve from deletion on error
494 int ret = open_datastream(stream);
495 if (ret == LIBRAW_SUCCESS)
497 ID.input_internal =1 ; // flag to delete datastream on recycle
499 else
501 delete stream;
502 ID.input_internal = 0;
504 return ret;
507 int LibRaw::open_buffer(void *buffer, size_t size)
509 // this stream will close on recycle()
510 if(!buffer || buffer==(void*)-1)
511 return LIBRAW_IO_ERROR;
513 LibRaw_buffer_datastream *stream = new LibRaw_buffer_datastream(buffer,size);
514 if(!stream->valid())
516 delete stream;
517 return LIBRAW_IO_ERROR;
519 ID.input_internal = 0; // preserve from deletion on error
520 int ret = open_datastream(stream);
521 if (ret == LIBRAW_SUCCESS)
523 ID.input_internal =1 ; // flag to delete datastream on recycle
525 else
527 delete stream;
528 ID.input_internal = 0;
530 return ret;
534 int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
537 if(!stream)
538 return ENOENT;
539 if(!stream->valid())
540 return LIBRAW_IO_ERROR;
541 recycle();
543 try {
544 ID.input = stream;
545 SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
547 if (O.use_camera_matrix < 0)
548 O.use_camera_matrix = O.use_camera_wb;
550 identify();
552 if(IO.fuji_width)
554 IO.fwidth = S.width;
555 IO.fheight = S.height;
556 S.iwidth = S.width = IO.fuji_width << !libraw_internal_data.unpacker_data.fuji_layout;
557 S.iheight = S.height = S.raw_height;
558 S.raw_height += 2*S.top_margin;
561 int saved_raw_width = S.raw_width;
562 int saved_width = S.width;
563 // from packed_12_load_raw
564 if ((load_raw == &LibRaw:: packed_12_load_raw) && (S.raw_width * 2 >= S.width * 3))
566 // raw_width is in bytes!
567 S.raw_width = S.raw_width * 2 / 3;
569 else if (S.pixel_aspect < 0.95 || S.pixel_aspect > 1.05)
571 S.width*=S.pixel_aspect;
574 if(S.raw_width>S.width + S.left_margin)
575 S.right_margin = S.raw_width - S.width - S.left_margin;
577 if(S.raw_height > S.height + S.top_margin)
578 S.bottom_margin = S.raw_height - S.height - S.top_margin;
580 S.raw_width = saved_raw_width;
581 S.width = saved_width;
583 if(C.profile_length)
585 if(C.profile) free(C.profile);
586 C.profile = malloc(C.profile_length);
587 merror(C.profile,"LibRaw::open_file()");
588 ID.input->seek(ID.profile_offset,SEEK_SET);
589 ID.input->read(C.profile,C.profile_length,1);
592 SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
594 catch ( LibRaw_exceptions err) {
595 EXCEPTION_HANDLER(err);
598 if(P1.raw_count < 1)
599 return LIBRAW_FILE_UNSUPPORTED;
601 if (O.user_flip >= 0)
602 S.flip = O.user_flip;
604 switch ((S.flip+3600) % 360)
606 case 270: S.flip = 5; break;
607 case 180: S.flip = 3; break;
608 case 90: S.flip = 6; break;
611 write_fun = &LibRaw::write_ppm_tiff;
613 if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
615 S.height += S.height & 1;
616 S.width += S.width & 1;
619 IO.shrink = P1.filters && (O.half_size || O.threshold || O.aber[0] != 1 || O.aber[2] != 1);
620 S.iheight = (S.height + IO.shrink) >> IO.shrink;
621 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
623 SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
626 return LIBRAW_SUCCESS;
629 int LibRaw::unpack(void)
631 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
632 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
633 try {
635 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
636 if (O.shot_select >= P1.raw_count)
637 return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
639 if(!load_raw)
640 return LIBRAW_UNSPECIFIED_ERROR;
642 if (O.use_camera_matrix && C.cmatrix[0][0] > 0.25)
644 memcpy (C.rgb_cam, C.cmatrix, sizeof (C.cmatrix));
645 IO.raw_color = 0;
647 // already allocated ?
648 if(imgdata.image) free(imgdata.image);
650 imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
651 merror (imgdata.image, "unpack()");
654 if(S.top_margin || S.left_margin || S.right_margin || S.bottom_margin)
656 unsigned sz = S.raw_height*(S.left_margin+S.right_margin)
657 + S.width*(S.top_margin+S.bottom_margin);
658 imgdata.masked_pixels.buffer = (ushort*) calloc(sz, sizeof(ushort));
659 merror (imgdata.masked_pixels.buffer, "unpack()");
660 init_masked_ptrs();
662 if (libraw_internal_data.unpacker_data.meta_length)
664 libraw_internal_data.internal_data.meta_data =
665 (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
666 merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
668 ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
669 // foveon_load_raw produces different data for document_mode, we'll
670 // deal with it in dcraw_document_mode_processing
671 int save_document_mode = O.document_mode;
672 O.document_mode = 0;
674 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
675 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
677 (this->*load_raw)();
679 O.document_mode = save_document_mode;
681 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
682 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
684 SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
685 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
687 return 0;
689 catch ( LibRaw_exceptions err) {
690 EXCEPTION_HANDLER(err);
694 int LibRaw::dcraw_document_mode_processing(void)
696 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
697 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
699 try {
701 if(IO.fwidth)
702 rotate_fuji_raw();
704 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
705 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
707 O.document_mode = 2;
708 if(P1.is_foveon)
710 // filter image data for foveon document mode
711 short *iptr = (short *)imgdata.image;
712 for (int i=0; i < S.height*S.width*4; i++)
714 if ((short) iptr[i] < 0)
715 iptr[i] = 0;
717 SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
720 O.use_fuji_rotate = 0;
721 if (!(O.filtering_mode & LIBRAW_FILTERING_NOZEROES) && IO.zero_is_bad)
723 remove_zeroes();
724 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
726 if(O.bad_pixels)
728 bad_pixels(O.bad_pixels);
729 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
731 if (O.dark_frame)
733 subtract (O.dark_frame);
734 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
736 if(O.filtering_mode & LIBRAW_FILTERING_NOBLACKS)
737 C.black=0;
739 if (O.user_black >= 0)
740 C.black = O.user_black;
742 if (O.user_sat > 0)
743 C.maximum = O.user_sat;
745 pre_interpolate();
746 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
748 if (libraw_internal_data.internal_output_params.mix_green)
750 int i;
751 for (P1.colors=3, i=0; i < S.height*S.width; i++)
752 imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
754 SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
756 if (!P1.is_foveon && P1.colors == 3)
757 median_filter();
758 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
760 if (!P1.is_foveon && O.highlight == 2)
761 blend_highlights();
763 if (!P1.is_foveon && O.highlight > 2)
764 recover_highlights();
765 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
767 if (O.use_fuji_rotate)
768 fuji_rotate();
769 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
770 #ifndef NO_LCMS
771 if(O.camera_profile)
773 apply_profile(O.camera_profile,O.output_profile);
774 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
776 #endif
777 if(!libraw_internal_data.output_data.histogram)
779 libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
780 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_document_mode_processing()");
782 convert_to_rgb();
783 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
785 if (O.use_fuji_rotate)
786 stretch();
787 SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
789 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
790 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
792 return 0;
794 catch ( LibRaw_exceptions err) {
795 EXCEPTION_HANDLER(err);
800 #if 1
801 #define FORC(cnt) for (c=0; c < cnt; c++)
802 #define FORCC FORC(ret->colors)
803 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
805 libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
807 if(!T.thumb)
809 if ( !ID.toffset)
811 if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
813 else
815 if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
817 return NULL;
820 if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
822 libraw_processed_image_t * ret =
823 (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
825 if(!ret)
827 if(errcode) *errcode= ENOMEM;
828 return NULL;
831 bzero(ret,sizeof(libraw_processed_image_t));
832 ret->type = LIBRAW_IMAGE_BITMAP;
833 ret->height = T.theight;
834 ret->width = T.twidth;
835 ret->colors = 3;
836 ret->bits = 8;
837 ret->gamma_corrected = 1;
838 ret->data_size = T.tlength;
839 memmove(ret->data,T.thumb,T.tlength);
840 if(errcode) *errcode= 0;
841 return ret;
843 else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
845 ushort exif[5];
846 int mk_exif = 0;
847 if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
849 int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
851 libraw_processed_image_t * ret =
852 (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
854 if(!ret)
856 if(errcode) *errcode= ENOMEM;
857 return NULL;
860 bzero(ret,sizeof(libraw_processed_image_t));
862 ret->type = LIBRAW_IMAGE_JPEG;
863 ret->data_size = dsize;
865 ret->data[0] = 0xff;
866 ret->data[1] = 0xd8;
867 if(mk_exif)
869 struct tiff_hdr th;
870 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
871 exif[1] = htons (8 + sizeof th);
872 memmove(ret->data+2,exif,sizeof(exif));
873 tiff_head (&th, 0);
874 memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
875 memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
877 else
879 memmove(ret->data+2,T.thumb+2,T.tlength-2);
881 if(errcode) *errcode= 0;
882 return ret;
885 else
887 if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
888 return NULL;
895 libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
897 if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE)
899 if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
900 return NULL;
903 if(!libraw_internal_data.output_data.histogram)
905 libraw_internal_data.output_data.histogram =
906 (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
907 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_make_mem_image()");
910 unsigned ds = S.height * S.width * (O.output_bps/8) * P1.colors;
911 libraw_processed_image_t *ret = (libraw_processed_image_t*)::malloc(sizeof(libraw_processed_image_t)+ds);
912 if(!ret)
914 if(errcode) *errcode= ENOMEM;
915 return NULL;
917 bzero(ret,sizeof(libraw_processed_image_t));
918 // metadata init
920 int s_iheight = S.iheight;
921 int s_iwidth = S.iwidth;
922 int s_width = S.width;
923 int s_hwight = S.height;
925 S.iheight = S.height;
926 S.iwidth = S.width;
929 if (S.flip & 4) SWAP(S.height,S.width);
932 ret->type = LIBRAW_IMAGE_BITMAP;
933 ret->height = S.height;
934 ret->width = S.width;
935 ret->colors = P1.colors;
936 ret->bits = O.output_bps;
937 ret->gamma_corrected = (O.output_bps == 8)?1:O.gamma_16bit;
939 ret->data_size = ds;
941 // Cut'n'paste from write_tiff_ppm, should be generalized later
942 uchar *bufp = ret->data;
943 uchar *ppm;
944 ushort *ppm2,lut16[0x10000];
945 int c, row, col, soff, rstep, cstep;
948 if (ret->bits == 8 || ret->gamma_corrected ) gamma_lut (lut16);
949 soff = flip_index (0, 0);
950 cstep = flip_index (0, 1) - soff;
951 rstep = flip_index (1, 0) - flip_index (0, S.width);
954 for (row=0; row < ret->height; row++, soff += rstep)
956 ppm2 = (ushort*) (ppm = bufp);
957 for (col=0; col < ret->width; col++, soff += cstep)
958 if (ret->bits == 8)
959 FORCC ppm [col*ret->colors+c] = lut16[imgdata.image[soff][c]]/256;
960 else if(ret->gamma_corrected)
961 FORCC ppm2[col*ret->colors+c] = lut16[imgdata.image[soff][c]];
962 else
963 FORCC ppm2[col*ret->colors+c] = imgdata.image[soff][c];
964 bufp+=ret->colors*(ret->bits/8)*ret->width;
966 if(errcode) *errcode= 0;
968 S.iheight = s_iheight;
969 S.iwidth = s_iwidth;
970 S.width = s_width;
971 S.height = s_hwight;
973 return ret;
976 #undef FORC
977 #undef FORCC
978 #undef SWAP
979 #endif
982 int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
984 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
986 if(!imgdata.image)
987 return LIBRAW_OUT_OF_ORDER_CALL;
989 if(!filename)
990 return ENOENT;
991 FILE *f = fopen(filename,"wb");
993 if(!f)
994 return errno;
996 try {
997 if(!libraw_internal_data.output_data.histogram)
999 libraw_internal_data.output_data.histogram =
1000 (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1001 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
1003 write_ppm_tiff(f);
1004 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1005 fclose(f);
1006 return 0;
1008 catch ( LibRaw_exceptions err) {
1009 fclose(f);
1010 EXCEPTION_HANDLER(err);
1014 void LibRaw::kodak_thumb_loader()
1016 // some kodak cameras
1017 ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
1018 int s_colors = P1.colors;
1019 unsigned s_filters = P1.filters;
1020 ushort (*s_image)[4] = imgdata.image;
1023 S.height = T.theight;
1024 S.width = T.twidth;
1025 P1.filters = 0;
1027 if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw)
1029 S.height += S.height & 1;
1030 S.width += S.width & 1;
1033 imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
1034 merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
1036 ID.input->seek(ID.toffset, SEEK_SET);
1037 // read kodak thumbnail into T.image[]
1038 (this->*thumb_load_raw)();
1040 // copy-n-paste from image pipe
1041 #define MIN(a,b) ((a) < (b) ? (a) : (b))
1042 #define MAX(a,b) ((a) > (b) ? (a) : (b))
1043 #define LIM(x,min,max) MAX(min,MIN(x,max))
1044 #define CLIP(x) LIM(x,0,65535)
1045 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
1047 // from scale_colors
1049 double dmax;
1050 float scale_mul[4];
1051 int c,val;
1052 for (dmax=DBL_MAX, c=0; c < 3; c++)
1053 if (dmax > C.pre_mul[c])
1054 dmax = C.pre_mul[c];
1056 for( c=0; c< 3; c++)
1057 scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
1058 scale_mul[3] = scale_mul[1];
1060 size_t size = S.height * S.width;
1061 for (int i=0; i < size*4 ; i++)
1063 val = imgdata.image[0][i];
1064 if(!val) continue;
1065 val *= scale_mul[i & 3];
1066 imgdata.image[0][i] = CLIP(val);
1070 // from convert_to_rgb
1071 ushort *img;
1072 int row,col;
1074 int (*t_hist)[LIBRAW_HISTOGRAM_SIZE] = (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
1075 merror (t_hist, "LibRaw::kodak_thumb_loader()");
1077 float out[3],
1078 out_cam[3][4] =
1080 {2.81761312, -1.98369181, 0.166078627, 0},
1081 {-0.111855984, 1.73688626, -0.625030339, 0},
1082 {-0.0379119813, -0.891268849, 1.92918086, 0}
1085 for (img=imgdata.image[0], row=0; row < S.height; row++)
1086 for (col=0; col < S.width; col++, img+=4)
1088 out[0] = out[1] = out[2] = 0;
1089 for(int c=0;c<3;c++)
1091 out[0] += out_cam[0][c] * img[c];
1092 out[1] += out_cam[1][c] * img[c];
1093 out[2] += out_cam[2][c] * img[c];
1095 for(int c=0; c<3; c++)
1096 img[c] = CLIP((int) out[c]);
1097 for(int c=0; c<P1.colors;c++)
1098 t_hist[c][img[c] >> 3]++;
1102 // from gamma_lut
1103 int (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
1104 libraw_internal_data.output_data.histogram = t_hist;
1106 ushort *lut16 = (ushort*)calloc(0x10000,sizeof(ushort));
1107 merror(lut16,"LibRaw::kodak_thumb_loader()");
1108 gamma_lut(lut16);
1110 libraw_internal_data.output_data.histogram = save_hist;
1112 free(t_hist);
1114 // from write_ppm_tiff - copy pixels into bitmap
1116 S.iheight = S.height;
1117 S.iwidth = S.width;
1118 if (S.flip & 4) SWAP(S.height,S.width);
1120 if(T.thumb) free(T.thumb);
1121 T.thumb = (char*) calloc (S.width * S.height, P1.colors);
1122 merror (T.thumb, "LibRaw::kodak_thumb_loader()");
1123 T.tlength = S.width * S.height * P1.colors;
1125 // from write_tiff_ppm
1127 int soff = flip_index (0, 0);
1128 int cstep = flip_index (0, 1) - soff;
1129 int rstep = flip_index (1, 0) - flip_index (0, S.width);
1131 for (int row=0; row < S.height; row++, soff += rstep)
1133 char *ppm = T.thumb + row*S.width*P1.colors;
1134 for (int col=0; col < S.width; col++, soff += cstep)
1135 for(int c = 0; c < P1.colors; c++)
1136 ppm [col*P1.colors+c] = lut16[imgdata.image[soff][c]]/256;
1139 free(lut16);
1140 // restore variables
1141 free(imgdata.image);
1142 imgdata.image = s_image;
1144 T.twidth = S.width;
1145 S.width = s_width;
1147 S.iwidth = s_iwidth;
1148 S.iheight = s_iheight;
1150 T.theight = S.height;
1151 S.height = s_height;
1153 T.tcolors = P1.colors;
1154 P1.colors = s_colors;
1156 P1.filters = s_filters;
1158 #undef MIN
1159 #undef MAX
1160 #undef LIM
1161 #undef CLIP
1162 #undef SWAP
1165 void LibRaw::foveon_thumb_loader (void)
1167 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
1168 struct decode *dindex;
1169 short pred[3];
1171 if(T.thumb) free(T.thumb);
1172 T.thumb = NULL;
1174 bwide = get4();
1175 if (bwide > 0)
1177 if (bwide < T.twidth*3) return;
1178 T.thumb = (char*)malloc(3*T.twidth * T.theight);
1179 merror (T.thumb, "foveon_thumb()");
1180 char *buf = (char*)malloc(bwide);
1181 merror (buf, "foveon_thumb()");
1182 for (row=0; row < T.theight; row++)
1184 ID.input->read(buf, 1, bwide);
1185 memmove(T.thumb+(row*T.twidth*3),buf,T.twidth*3);
1187 free(buf);
1188 T.tlength = 3*T.twidth * T.theight;
1189 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1190 return;
1192 else
1194 foveon_decoder (256, 0);
1195 T.thumb = (char*)malloc(3*T.twidth * T.theight);
1196 char *bufp = T.thumb;
1197 merror (T.thumb, "foveon_thumb()");
1198 for (row=0; row < T.theight; row++)
1200 memset (pred, 0, sizeof pred);
1201 if (!bit) get4();
1202 for (bit=col=0; col < T.twidth; col++)
1203 for(c=0;c<3;c++)
1205 for (dindex=first_decode; dindex->branch[0]; )
1207 if ((bit = (bit-1) & 31) == 31)
1208 for (i=0; i < 4; i++)
1209 bitbuf = (bitbuf << 8) + ID.input->get_char();
1210 dindex = dindex->branch[bitbuf >> bit & 1];
1212 pred[c] += dindex->leaf;
1213 (*bufp++)=pred[c];
1216 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1217 T.tlength = 3*T.twidth * T.theight;
1219 return;
1223 // Äîñòàåò thumbnail èç ôàéëà, ñòàâèò thumb_format â ñîîòâåòñòâèè ñ ôîðìàòîì
1224 int LibRaw::unpack_thumb(void)
1226 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1227 CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
1229 try {
1230 if ( !ID.toffset)
1232 return LIBRAW_NO_THUMBNAIL;
1234 else if (thumb_load_raw)
1236 kodak_thumb_loader();
1237 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1238 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1239 return 0;
1241 else
1243 ID.input->seek(ID.toffset, SEEK_SET);
1244 if ( write_thumb == &LibRaw::jpeg_thumb)
1246 if(T.thumb) free(T.thumb);
1247 T.thumb = (char *) malloc (T.tlength);
1248 merror (T.thumb, "jpeg_thumb()");
1249 ID.input->read (T.thumb, 1, T.tlength);
1250 T.tcolors = 3;
1251 T.tformat = LIBRAW_THUMBNAIL_JPEG;
1252 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1253 return 0;
1255 else if (write_thumb == &LibRaw::ppm_thumb)
1257 T.tlength = T.twidth * T.theight*3;
1258 if(T.thumb) free(T.thumb);
1260 T.thumb = (char *) malloc (T.tlength);
1261 merror (T.thumb, "ppm_thumb()");
1263 ID.input->read(T.thumb, 1, T.tlength);
1265 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1266 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1267 return 0;
1270 else if (write_thumb == &LibRaw::foveon_thumb)
1272 foveon_thumb_loader();
1273 // may return with error, so format is set in
1274 // foveon thumb loader itself
1275 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1276 return 0;
1278 // else if -- all other write_thumb cases!
1279 else
1281 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1284 // last resort
1285 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1287 catch ( LibRaw_exceptions err) {
1288 EXCEPTION_HANDLER(err);
1293 int LibRaw::dcraw_thumb_writer(const char *fname)
1295 // CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);
1297 if(!fname)
1298 return ENOENT;
1300 FILE *tfp = fopen(fname,"wb");
1302 if(!tfp)
1303 return errno;
1305 if(!T.thumb)
1307 fclose(tfp);
1308 return LIBRAW_OUT_OF_ORDER_CALL;
1311 try {
1312 switch (T.tformat)
1314 case LIBRAW_THUMBNAIL_JPEG:
1315 jpeg_thumb_writer (tfp,T.thumb,T.tlength);
1316 break;
1317 case LIBRAW_THUMBNAIL_BITMAP:
1318 fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
1319 fwrite (T.thumb, 1, T.tlength, tfp);
1320 break;
1321 default:
1322 fclose(tfp);
1323 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1325 fclose(tfp);
1326 return 0;
1328 catch ( LibRaw_exceptions err) {
1329 fclose(tfp);
1330 EXCEPTION_HANDLER(err);
1334 int LibRaw::adjust_sizes_info_only(void)
1336 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1337 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_FUJI_ROTATE);
1338 if (O.use_fuji_rotate)
1340 if (IO.fuji_width)
1342 // restore saved values
1343 if(IO.fheight)
1345 S.height = IO.fheight;
1346 S.width = IO.fwidth;
1347 S.iheight = (S.height + IO.shrink) >> IO.shrink;
1348 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
1349 S.raw_height -= 2*S.top_margin;
1350 IO.fheight = IO.fwidth = 0; // prevent repeated calls
1352 // dcraw code
1353 IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
1354 S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
1355 S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
1357 else
1359 if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
1360 if (S.pixel_aspect > 1) S.iwidth = (ushort) (S.iwidth * S.pixel_aspect + 0.5);
1363 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1364 if (S.flip & 4)
1366 unsigned short t = S.iheight;
1367 S.iheight=S.iwidth;
1368 S.iwidth = t;
1369 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1371 return 0;
1374 int LibRaw::rotate_fuji_raw(void)
1376 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1377 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1380 if(!IO.fwidth) return LIBRAW_SUCCESS;
1381 int row,col,r,c;
1382 ushort (*newimage)[4];
1383 ushort fiwidth,fiheight;
1385 fiheight = (IO.fheight + IO.shrink) >> IO.shrink;
1386 fiwidth = (IO.fwidth + IO.shrink) >> IO.shrink;
1388 newimage = (ushort (*)[4]) calloc (fiheight*fiwidth, sizeof (*newimage));
1389 merror(newimage,"rotate_fuji_raw()");
1390 for(row=0;row<S.height;row++)
1392 for(col=0;col<S.width;col++)
1395 if (libraw_internal_data.unpacker_data.fuji_layout) {
1396 r = IO.fuji_width - 1 - col + (row >> 1);
1397 c = col + ((row+1) >> 1);
1398 } else {
1399 r = IO.fuji_width - 1 + row - (col >> 1);
1400 c = row + ((col+1) >> 1);
1402 newimage[((r) >> IO.shrink)*fiwidth + ((c) >> IO.shrink)][FC(r,c)] =
1403 imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][FC(r,c)];
1406 // restore fuji sizes!
1407 S.height = IO.fheight;
1408 S.width = IO.fwidth;
1409 S.iheight = (S.height + IO.shrink) >> IO.shrink;
1410 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
1411 S.raw_height -= 2*S.top_margin;
1412 IO.fheight = IO.fwidth = 0; // prevent repeated calls
1414 free(imgdata.image);
1415 imgdata.image = newimage;
1416 return LIBRAW_SUCCESS;
1421 int LibRaw::dcraw_process(void)
1423 int quality,i;
1426 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1427 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1429 try {
1431 if(IO.fwidth)
1432 rotate_fuji_raw();
1435 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
1436 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
1438 if(O.half_size)
1439 O.four_color_rgb = 1;
1441 if (!(O.filtering_mode & LIBRAW_FILTERING_NOZEROES) && IO.zero_is_bad)
1443 remove_zeroes();
1444 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
1446 if(O.bad_pixels)
1448 bad_pixels(O.bad_pixels);
1449 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
1451 if (O.dark_frame)
1453 subtract (O.dark_frame);
1454 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
1457 quality = 2 + !IO.fuji_width;
1459 if(O.filtering_mode & LIBRAW_FILTERING_NOBLACKS)
1460 C.black=0;
1462 if (O.user_qual >= 0) quality = O.user_qual;
1463 if (O.user_black >= 0) C.black = O.user_black;
1464 if (O.user_sat > 0) C.maximum = O.user_sat;
1466 if (P1.is_foveon && !O.document_mode)
1468 foveon_interpolate();
1469 SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
1472 if (!P1.is_foveon && O.document_mode < 2)
1474 scale_colors();
1475 SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
1478 pre_interpolate();
1479 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1481 if (P1.filters && !O.document_mode)
1483 if (quality == 0)
1484 lin_interpolate();
1485 else if (quality == 1 || P1.colors > 3)
1486 vng_interpolate();
1487 else if (quality == 2)
1488 ppg_interpolate();
1489 else
1490 ahd_interpolate();
1491 SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
1493 if (IO.mix_green)
1495 for (P1.colors=3, i=0; i < S.height * S.width; i++)
1496 imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
1497 SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
1500 if(!P1.is_foveon)
1502 if (P1.colors == 3)
1504 median_filter();
1505 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
1508 if (O.highlight == 2)
1510 blend_highlights();
1511 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1514 if (O.highlight > 2)
1516 recover_highlights();
1517 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1520 if (O.use_fuji_rotate)
1522 fuji_rotate();
1523 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1526 if(!libraw_internal_data.output_data.histogram)
1528 libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1529 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
1531 #ifndef NO_LCMS
1532 if(O.camera_profile)
1534 apply_profile(O.camera_profile,O.output_profile);
1535 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
1537 #endif
1539 convert_to_rgb();
1540 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
1542 if (O.use_fuji_rotate)
1544 stretch();
1545 SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
1547 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
1548 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
1549 return 0;
1551 catch ( LibRaw_exceptions err) {
1552 EXCEPTION_HANDLER(err);
1556 // Supported cameras:
1557 static const char *static_camera_list[] =
1559 "Adobe Digital Negative (DNG)",
1560 "Apple QuickTake 100",
1561 "Apple QuickTake 150",
1562 "Apple QuickTake 200",
1563 "AVT F-080C",
1564 "AVT F-145C",
1565 "AVT F-201C",
1566 "AVT F-510C",
1567 "AVT F-810C",
1568 "Canon PowerShot 600",
1569 "Canon PowerShot A5",
1570 "Canon PowerShot A5 Zoom",
1571 "Canon PowerShot A50",
1572 "Canon PowerShot A460 (CHDK hack)",
1573 "Canon PowerShot A530 (CHDK hack)",
1574 "Canon PowerShot A610 (CHDK hack)",
1575 "Canon PowerShot A620 (CHDK hack)",
1576 "Canon PowerShot A630 (CHDK hack)",
1577 "Canon PowerShot A640 (CHDK hack)",
1578 "Canon PowerShot A650 (CHDK hack)",
1579 "Canon PowerShot A710 IS (CHDK hack)",
1580 "Canon PowerShot A720 IS (CHDK hack)",
1581 "Canon PowerShot Pro70",
1582 "Canon PowerShot Pro90 IS",
1583 "Canon PowerShot G1",
1584 "Canon PowerShot G2",
1585 "Canon PowerShot G3",
1586 "Canon PowerShot G5",
1587 "Canon PowerShot G6",
1588 "Canon PowerShot G7 (CHDK hack)",
1589 "Canon PowerShot G9",
1590 "Canon PowerShot G10",
1591 "Canon PowerShot S2 IS (CHDK hack)",
1592 "Canon PowerShot S3 IS (CHDK hack)",
1593 "Canon PowerShot S5 IS (CHDK hack)",
1594 "Canon PowerShot SD300 (CHDK hack)",
1595 "Canon PowerShot S30",
1596 "Canon PowerShot S40",
1597 "Canon PowerShot S45",
1598 "Canon PowerShot S50",
1599 "Canon PowerShot S60",
1600 "Canon PowerShot S70",
1601 "Canon PowerShot Pro1",
1602 "Canon EOS D30",
1603 "Canon EOS D60",
1604 "Canon EOS 5D",
1605 "Canon EOS 5D Mark II",
1606 "Canon EOS 10D",
1607 "Canon EOS 20D",
1608 "Canon EOS 30D",
1609 "Canon EOS 40D",
1610 "Canon EOS 50D",
1611 "Canon EOS 300D / Digital Rebel / Kiss Digital",
1612 "Canon EOS 350D / Digital Rebel XT / Kiss Digital N",
1613 "Canon EOS 400D / Digital Rebel XTi / Kiss Digital X",
1614 "Canon EOS 450D / Digital Rebel XSi / Kiss Digital X2",
1615 "Canon EOS 1000D / Digital Rebel XS / Kiss Digital F",
1616 "Canon EOS D2000C",
1617 "Canon EOS-1D",
1618 "Canon EOS-1DS",
1619 "Canon EOS-1D Mark II",
1620 "Canon EOS-1D Mark III",
1621 "Canon EOS-1D Mark II N",
1622 "Canon EOS-1Ds Mark II",
1623 "Canon EOS-1Ds Mark III",
1624 "Casio QV-2000UX",
1625 "Casio QV-3000EX",
1626 "Casio QV-3500EX",
1627 "Casio QV-4000",
1628 "Casio QV-5700",
1629 "Casio QV-R41",
1630 "Casio QV-R51",
1631 "Casio QV-R61",
1632 "Casio EX-S100",
1633 "Casio EX-Z4",
1634 "Casio EX-Z50",
1635 "Casio EX-Z55",
1636 "Casio Exlim Pro 505",
1637 "Casio Exlim Pro 600",
1638 "Casio Exlim Pro 700",
1639 "Contax N Digital",
1640 "Creative PC-CAM 600",
1641 "Epson R-D1",
1642 "Foculus 531C",
1643 "Fuji FinePix E550",
1644 "Fuji FinePix E900",
1645 "Fuji FinePix F700",
1646 "Fuji FinePix F710",
1647 "Fuji FinePix F800",
1648 "Fuji FinePix F810",
1649 "Fuji FinePix S2Pro",
1650 "Fuji FinePix S3Pro",
1651 "Fuji FinePix S5Pro",
1652 "Fuji FinePix S20Pro",
1653 "Fuji FinePix S100FS",
1654 "Fuji FinePix S5000",
1655 "Fuji FinePix S5100/S5500",
1656 "Fuji FinePix S5200/S5600",
1657 "Fuji FinePix S6000fd",
1658 "Fuji FinePix S7000",
1659 "Fuji FinePix S9000/S9500",
1660 "Fuji FinePix S9100/S9600",
1661 "Fuji IS-1",
1662 "Hasselblad CFV",
1663 "Hasselblad H3D",
1664 "Hasselblad V96C",
1665 "Imacon Ixpress 16-megapixel",
1666 "Imacon Ixpress 22-megapixel",
1667 "Imacon Ixpress 39-megapixel",
1668 "ISG 2020x1520",
1669 "Kodak DC20 (see Oliver Hartman's page)",
1670 "Kodak DC25 (see Jun-ichiro Itoh's page)",
1671 "Kodak DC40",
1672 "Kodak DC50",
1673 "Kodak DC120 (also try kdc2tiff)",
1674 "Kodak DCS200",
1675 "Kodak DCS315C",
1676 "Kodak DCS330C",
1677 "Kodak DCS420",
1678 "Kodak DCS460",
1679 "Kodak DCS460A",
1680 "Kodak DCS520C",
1681 "Kodak DCS560C",
1682 "Kodak DCS620C",
1683 "Kodak DCS620X",
1684 "Kodak DCS660C",
1685 "Kodak DCS660M",
1686 "Kodak DCS720X",
1687 "Kodak DCS760C",
1688 "Kodak DCS760M",
1689 "Kodak EOSDCS1",
1690 "Kodak EOSDCS3B",
1691 "Kodak NC2000F",
1692 "Kodak ProBack",
1693 "Kodak PB645C",
1694 "Kodak PB645H",
1695 "Kodak PB645M",
1696 "Kodak DCS Pro 14n",
1697 "Kodak DCS Pro 14nx",
1698 "Kodak DCS Pro SLR/c",
1699 "Kodak DCS Pro SLR/n",
1700 "Kodak C330",
1701 "Kodak C603",
1702 "Kodak P850",
1703 "Kodak P880",
1704 "Kodak KAI-0340",
1705 "Konica KD-400Z",
1706 "Konica KD-510Z",
1707 "Leaf AFi 7",
1708 "Leaf Aptus 17",
1709 "Leaf Aptus 22",
1710 "Leaf Aptus 54S",
1711 "Leaf Aptus 65",
1712 "Leaf Aptus 75",
1713 "Leaf Aptus 75S",
1714 "Leaf Cantare",
1715 "Leaf CatchLight",
1716 "Leaf CMost",
1717 "Leaf DCB2",
1718 "Leaf Valeo 6",
1719 "Leaf Valeo 11",
1720 "Leaf Valeo 17",
1721 "Leaf Valeo 22",
1722 "Leaf Volare",
1723 "Leica Digilux 2",
1724 "Leica Digilux 3",
1725 "Leica D-LUX2",
1726 "Leica D-LUX3",
1727 "Leica D-LUX4",
1728 "Leica V-LUX1",
1729 "Logitech Fotoman Pixtura",
1730 "Mamiya ZD",
1731 "Micron 2010",
1732 "Minolta RD175",
1733 "Minolta DiMAGE 5",
1734 "Minolta DiMAGE 7",
1735 "Minolta DiMAGE 7i",
1736 "Minolta DiMAGE 7Hi",
1737 "Minolta DiMAGE A1",
1738 "Minolta DiMAGE A2",
1739 "Minolta DiMAGE A200",
1740 "Minolta DiMAGE G400",
1741 "Minolta DiMAGE G500",
1742 "Minolta DiMAGE G530",
1743 "Minolta DiMAGE G600",
1744 "Minolta DiMAGE Z2",
1745 "Minolta Alpha/Dynax/Maxxum 5D",
1746 "Minolta Alpha/Dynax/Maxxum 7D",
1747 "Nikon D1",
1748 "Nikon D1H",
1749 "Nikon D1X",
1750 "Nikon D2H",
1751 "Nikon D2Hs",
1752 "Nikon D2X",
1753 "Nikon D2Xs",
1754 "Nikon D3",
1755 "Nikon D3X",
1756 "Nikon D40",
1757 "Nikon D40X",
1758 "Nikon D50",
1759 "Nikon D60",
1760 "Nikon D70",
1761 "Nikon D70s",
1762 "Nikon D80",
1763 "Nikon D90",
1764 "Nikon D100",
1765 "Nikon D200",
1766 "Nikon D300",
1767 "Nikon D700",
1768 "Nikon E700 (\"DIAG RAW\" hack)",
1769 "Nikon E800 (\"DIAG RAW\" hack)",
1770 "Nikon E880 (\"DIAG RAW\" hack)",
1771 "Nikon E900 (\"DIAG RAW\" hack)",
1772 "Nikon E950 (\"DIAG RAW\" hack)",
1773 "Nikon E990 (\"DIAG RAW\" hack)",
1774 "Nikon E995 (\"DIAG RAW\" hack)",
1775 "Nikon E2100 (\"DIAG RAW\" hack)",
1776 "Nikon E2500 (\"DIAG RAW\" hack)",
1777 "Nikon E3200 (\"DIAG RAW\" hack)",
1778 "Nikon E3700 (\"DIAG RAW\" hack)",
1779 "Nikon E4300 (\"DIAG RAW\" hack)",
1780 "Nikon E4500 (\"DIAG RAW\" hack)",
1781 "Nikon E5000",
1782 "Nikon E5400",
1783 "Nikon E5700",
1784 "Nikon E8400",
1785 "Nikon E8700",
1786 "Nikon E8800",
1787 "Nikon Coolpix P6000",
1788 "Nikon Coolpix S6 (\"DIAG RAW\" hack)",
1789 "Nokia N95",
1790 "Olympus C3030Z",
1791 "Olympus C5050Z",
1792 "Olympus C5060WZ",
1793 "Olympus C7070WZ",
1794 "Olympus C70Z,C7000Z",
1795 "Olympus C740UZ",
1796 "Olympus C770UZ",
1797 "Olympus C8080WZ",
1798 "Olympus E-1",
1799 "Olympus E-3",
1800 "Olympus E-10",
1801 "Olympus E-20",
1802 "Olympus E-300",
1803 "Olympus E-330",
1804 "Olympus E-400",
1805 "Olympus E-410",
1806 "Olympus E-420",
1807 "Olympus E-500",
1808 "Olympus E-510",
1809 "Olympus E-520",
1810 "Olympus SP310",
1811 "Olympus SP320",
1812 "Olympus SP350",
1813 "Olympus SP500UZ",
1814 "Olympus SP510UZ",
1815 "Olympus SP550UZ",
1816 "Olympus SP560UZ",
1817 "Olympus SP570UZ",
1818 "Panasonic DMC-FZ8",
1819 "Panasonic DMC-FZ18",
1820 "Panasonic DMC-FZ28",
1821 "Panasonic DMC-FZ30",
1822 "Panasonic DMC-FZ50",
1823 "Panasonic DMC-FX150",
1824 "Panasonic DMC-G1",
1825 "Panasonic DMC-L1",
1826 "Panasonic DMC-L10",
1827 "Panasonic DMC-LC1",
1828 "Panasonic DMC-LX1",
1829 "Panasonic DMC-LX2",
1830 "Panasonic DMC-LX3",
1831 "Pentax *ist D",
1832 "Pentax *ist DL",
1833 "Pentax *ist DL2",
1834 "Pentax *ist DS",
1835 "Pentax *ist DS2",
1836 "Pentax K10D",
1837 "Pentax K20D",
1838 "Pentax K100D",
1839 "Pentax K100D Super",
1840 "Pentax K200D",
1841 "Pentax K2000/K-m",
1842 "Pentax Optio S",
1843 "Pentax Optio S4",
1844 "Pentax Optio 33WR",
1845 "Pentax Optio 750Z",
1846 "Phase One LightPhase",
1847 "Phase One H 10",
1848 "Phase One H 20",
1849 "Phase One H 25",
1850 "Phase One P 20",
1851 "Phase One P 25",
1852 "Phase One P 30",
1853 "Phase One P 45",
1854 "Pixelink A782",
1855 "Polaroid x530",
1856 "Rollei d530flex",
1857 "RoverShot 3320af",
1858 "Samsung GX-1S",
1859 "Samsung GX-10",
1860 "Samsung S85 (hacked)",
1861 "Sarnoff 4096x5440",
1862 "Sigma SD9",
1863 "Sigma SD10",
1864 "Sigma SD14",
1865 "Sinar 3072x2048",
1866 "Sinar 4080x4080",
1867 "Sinar 4080x5440",
1868 "Sinar STI format",
1869 "SMaL Ultra-Pocket 3",
1870 "SMaL Ultra-Pocket 4",
1871 "SMaL Ultra-Pocket 5",
1872 "Sony DSC-F828",
1873 "Sony DSC-R1",
1874 "Sony DSC-V3",
1875 "Sony DSLR-A100",
1876 "Sony DSLR-A200",
1877 "Sony DSLR-A300",
1878 "Sony DSLR-A350",
1879 "Sony DSLR-A700",
1880 "Sony DSLR-A900",
1881 "Sony XCD-SX910CR",
1882 "STV680 VGA",
1883 NULL
1886 const char** LibRaw::cameraList() { return static_camera_list;}
1887 int LibRaw::cameraCount() { return (sizeof(static_camera_list)/sizeof(static_camera_list[0]))-1; }
1890 const char * LibRaw::strprogress(enum LibRaw_progress p)
1892 switch(p)
1894 case LIBRAW_PROGRESS_START:
1895 return "Starting";
1896 case LIBRAW_PROGRESS_OPEN :
1897 return "Opening file";
1898 case LIBRAW_PROGRESS_IDENTIFY :
1899 return "Reading metadata";
1900 case LIBRAW_PROGRESS_SIZE_ADJUST:
1901 return "Adjusting size";
1902 case LIBRAW_PROGRESS_LOAD_RAW:
1903 return "Reading RAW data";
1904 case LIBRAW_PROGRESS_REMOVE_ZEROES:
1905 return "Clearing zero values";
1906 case LIBRAW_PROGRESS_BAD_PIXELS :
1907 return "Removing dead pixels";
1908 case LIBRAW_PROGRESS_DARK_FRAME:
1909 return "Subtracting dark frame data";
1910 case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
1911 return "Interpolating Foveon sensor data";
1912 case LIBRAW_PROGRESS_SCALE_COLORS:
1913 return "Scaling colors";
1914 case LIBRAW_PROGRESS_PRE_INTERPOLATE:
1915 return "Pre-interpolating";
1916 case LIBRAW_PROGRESS_INTERPOLATE:
1917 return "Interpolating";
1918 case LIBRAW_PROGRESS_MIX_GREEN :
1919 return "Mixing green channels";
1920 case LIBRAW_PROGRESS_MEDIAN_FILTER :
1921 return "Median filter";
1922 case LIBRAW_PROGRESS_HIGHLIGHTS:
1923 return "Highlight recovery";
1924 case LIBRAW_PROGRESS_FUJI_ROTATE :
1925 return "Rotating Fuji diagonal data";
1926 case LIBRAW_PROGRESS_FLIP :
1927 return "Flipping image";
1928 case LIBRAW_PROGRESS_APPLY_PROFILE:
1929 return "ICC conversion";
1930 case LIBRAW_PROGRESS_CONVERT_RGB:
1931 return "Converting to RGB";
1932 case LIBRAW_PROGRESS_STRETCH:
1933 return "Stretching image";
1934 case LIBRAW_PROGRESS_THUMB_LOAD:
1935 return "Loading thumbnail";
1936 default:
1937 return "Some strange things";