libkipi from trunk (KDE 4.3) : add support of kipi host settings "file timestamp...
[kdegraphics.git] / libs / libkdcraw / libraw / src / libraw_cxx.cpp
blob8e0c55acfdf9e47b4b88997fdff59a8077dbdaef
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, 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);
33 else
34 fprintf (stderr,"%s: data corrupted at %d\n",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)
120 if (feof(libraw_internal_data.internal_data.input))
122 if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
123 libraw_internal_data.internal_data.ifname,-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.ifname,
130 ftell(libraw_internal_data.internal_data.input));
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 unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
140 #ifdef DCRAW_VERBOSE
141 verbose = 1;
142 #else
143 verbose = 0;
144 #endif
145 bzero(&imgdata,sizeof(imgdata));
146 bzero(&libraw_internal_data,sizeof(libraw_internal_data));
147 bzero(&callbacks,sizeof(callbacks));
148 callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL: &default_memory_callback;
149 callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
150 memmove(&imgdata.params.aber,&aber,sizeof(aber));
151 memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
153 imgdata.params.bright=1;
154 imgdata.params.use_camera_matrix=-1;
155 imgdata.params.user_flip=-1;
156 imgdata.params.user_black=-1;
157 imgdata.params.user_sat=-1;
158 imgdata.params.user_qual=-1;
159 imgdata.params.output_color=1;
160 imgdata.params.output_bps=8;
161 imgdata.params.use_fuji_rotate=1;
162 imgdata.parent_class = this;
163 imgdata.progress_flags = 0;
164 tls = new LibRaw_TLS;
165 tls->init();
169 void* LibRaw:: malloc(size_t t)
171 void *p = memmgr.malloc(t);
172 return p;
174 void* LibRaw:: calloc(size_t n,size_t t)
176 void *p = memmgr.calloc(n,t);
177 return p;
179 void LibRaw:: free(void *p)
181 memmgr.free(p);
185 int LibRaw:: fc (int row, int col)
187 static const char filter[16][16] =
188 { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
189 { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
190 { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
191 { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
192 { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
193 { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
194 { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
195 { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
196 { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
197 { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
198 { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
199 { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
200 { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
201 { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
202 { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
203 { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
205 if (imgdata.idata.filters != 1) return FC(row,col);
206 return filter[(row+imgdata.sizes.top_margin) & 15][(col+imgdata.sizes.left_margin) & 15];
209 void LibRaw:: recycle()
211 if(libraw_internal_data.internal_data.input)
213 fclose(libraw_internal_data.internal_data.input);
214 libraw_internal_data.internal_data.input = NULL;
216 #define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
218 FREE(imgdata.image);
219 FREE(imgdata.thumbnail.thumb);
220 FREE(libraw_internal_data.internal_data.meta_data);
221 FREE(libraw_internal_data.output_data.histogram);
222 FREE(libraw_internal_data.output_data.oprof);
223 FREE(imgdata.color.profile);
224 FREE(imgdata.masked_pixels.buffer);
225 #undef FREE
226 bzero(&imgdata.masked_pixels,sizeof(imgdata.masked_pixels));
227 bzero(&imgdata.sizes,sizeof(imgdata.sizes));
228 memmgr.cleanup();
229 imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
230 imgdata.progress_flags = 0;
232 // zero all data fields ???
233 // bzero(&imgdata,sizeof(imgdata));
234 // bzero(&libraw_internal_data,sizeof(libraw_internal_data));
236 tls->init();
239 const char * LibRaw::unpack_function_name()
241 if(!load_raw) return "Function not set";
243 // sorted names order
244 if (load_raw == &LibRaw::adobe_dng_load_raw_lj) return "adobe_dng_load_raw_lj()";
245 if (load_raw == &LibRaw::adobe_dng_load_raw_nc) return "adobe_dng_load_raw_nc()";
246 if (load_raw == &LibRaw::canon_600_load_raw) return "canon_600_load_raw()";
248 if (load_raw == &LibRaw::canon_a5_load_raw) return "canon_a5_load_raw()";
249 if (load_raw == &LibRaw::canon_compressed_load_raw) return "canon_compressed_load_raw()";
250 if (load_raw == &LibRaw::canon_sraw_load_raw) return "canon_sraw_load_raw()";
252 if (load_raw == &LibRaw::casio_qv5700_load_raw ) return "casio_qv5700_load_raw()";
253 if (load_raw == &LibRaw::eight_bit_load_raw ) return "eight_bit_load_raw()";
254 if (load_raw == &LibRaw::foveon_load_raw ) return "foveon_load_raw()";
255 if (load_raw == &LibRaw::fuji_load_raw ) return "fuji_load_raw()";
256 // 10
257 if (load_raw == &LibRaw::hasselblad_load_raw ) return "hasselblad_load_raw()";
258 if (load_raw == &LibRaw::imacon_full_load_raw ) return "imacon_full_load_raw()";
259 if (load_raw == &LibRaw::kodak_262_load_raw ) return "kodak_262_load_raw()";
261 if (load_raw == &LibRaw::kodak_65000_load_raw ) return "kodak_65000_load_raw()";
262 if (load_raw == &LibRaw::kodak_dc120_load_raw ) return "kodak_dc120_load_raw()";
263 if (load_raw == &LibRaw::kodak_jpeg_load_raw ) return "kodak_jpeg_load_raw()";
265 if (load_raw == &LibRaw::kodak_radc_load_raw ) return "kodak_radc_load_raw()";
266 if (load_raw == &LibRaw::kodak_rgb_load_raw ) return "kodak_rgb_load_raw()";
267 if (load_raw == &LibRaw::kodak_yrgb_load_raw ) return "kodak_yrgb_load_raw()";
268 if (load_raw == &LibRaw::kodak_ycbcr_load_raw ) return "kodak_ycbcr_load_raw()";
269 // 20
270 if (load_raw == &LibRaw::leaf_hdr_load_raw ) return "leaf_hdr_load_raw()";
271 if (load_raw == &LibRaw::lossless_jpeg_load_raw) return "lossless_jpeg_load_raw()";
272 if (load_raw == &LibRaw::minolta_rd175_load_raw ) return "minolta_rd175_load_raw()";
274 if (load_raw == &LibRaw::nikon_compressed_load_raw) return "nikon_compressed_load_raw()";
275 if (load_raw == &LibRaw::nikon_e900_load_raw ) return "nikon_e900_load_raw()";
276 if (load_raw == &LibRaw::nokia_load_raw ) return "nokia_load_raw()";
278 if (load_raw == &LibRaw::olympus_e300_load_raw ) return "olympus_e300_load_raw()";
279 if (load_raw == &LibRaw::olympus_e410_load_raw ) return "olympus_e410_load_raw()";
280 if (load_raw == &LibRaw::packed_12_load_raw ) return "packed_12_load_raw()";
281 if (load_raw == &LibRaw::panasonic_load_raw ) return "panasonic_load_raw()";
282 // 30
283 if (load_raw == &LibRaw::pentax_k10_load_raw ) return "pentax_k10_load_raw()";
284 if (load_raw == &LibRaw::phase_one_load_raw ) return "phase_one_load_raw()";
285 if (load_raw == &LibRaw::phase_one_load_raw_c ) return "phase_one_load_raw_c()";
287 if (load_raw == &LibRaw::quicktake_100_load_raw ) return "quicktake_100_load_raw()";
288 if (load_raw == &LibRaw::rollei_load_raw ) return "rollei_load_raw()";
289 if (load_raw == &LibRaw::sinar_4shot_load_raw ) return "sinar_4shot_load_raw()";
291 if (load_raw == &LibRaw::smal_v6_load_raw ) return "smal_v6_load_raw()";
292 if (load_raw == &LibRaw::smal_v9_load_raw ) return "smal_v9_load_raw()";
293 if (load_raw == &LibRaw::sony_load_raw ) return "sony_load_raw()";
294 if (load_raw == &LibRaw::sony_arw_load_raw ) return "sony_arw_load_raw()";
295 // 40
296 if (load_raw == &LibRaw::sony_arw2_load_raw ) return "sony_arw2_load_raw()";
297 if (load_raw == &LibRaw::unpacked_load_raw ) return "unpacked_load_raw()";
298 // 42 total
300 return "Unknown unpack function";
304 void LibRaw:: merror (void *ptr, const char *where)
306 if (ptr) return;
307 if(callbacks.mem_cb)(*callbacks.mem_cb)(callbacks.memcb_data,
308 libraw_internal_data.internal_data.ifname,where);
309 throw LIBRAW_EXCEPTION_ALLOC;
312 ushort * LibRaw::get_masked_pointer(int row, int col)
314 if(row<0 || col < 0) return NULL;
315 if(!M.buffer) return NULL;
316 if(row < S.top_margin)
318 // top band
319 if(col < S.left_margin)
321 return &(M.tl[row*S.left_margin+col]);
323 else if (col < S.left_margin + S.width)
325 int icol = col - S.left_margin;
326 return &(M.top[row*S.width+icol]);
328 else if (col < S.raw_width)
330 int icol = col - S.left_margin - S.width;
331 return &(M.tr[row*S.right_margin+icol]);
333 else
334 return NULL; // out of bounds
336 else if (row < S.top_margin + S.height)
338 //normal image height
339 int irow = row - S.top_margin;
340 if(col < S.left_margin)
342 return &M.left[irow*S.left_margin + col];
344 else if (col < S.left_margin + S.width)
346 // central image
347 return NULL;
349 else if (col < S.raw_width)
351 int icol = col - S.left_margin - S.width;
352 return &M.right[irow*S.right_margin+icol];
354 else
355 return NULL; // out of bounds
357 else if (row < S.raw_height)
359 int irow = row - S.top_margin - S.height;
360 // bottom band
361 if(col < S.left_margin)
363 return &M.bl[irow*S.left_margin+col];
365 else if (col < S.left_margin + S.width)
367 int icol = col - S.left_margin;
368 return &M.bottom[irow*S.width + icol];
370 else if (col < S.raw_width)
372 int icol = col - S.left_margin - S.width;
373 return &M.br[irow*S.right_margin + icol];
375 else
376 return NULL; // out of bounds
378 else
380 // out of bounds
381 return NULL;
383 // fallback
384 return NULL;
387 void LibRaw:: init_masked_ptrs()
389 if(!M.buffer) return;
391 // top band
392 M.tl = M.buffer;
393 M.top = M.tl +(S.top_margin*S.left_margin);
394 M.tr = M.top + (S.top_margin*S.width);
396 // left-right
397 M.left = M.tr + (S.top_margin * S.right_margin);
398 M.right = M.left + (S.left_margin * S.height);
400 // bottom band
401 M.bl = M.right + (S.right_margin * S.height);
402 M.bottom = M.bl + (S.left_margin * S.bottom_margin);
403 M.br = M.bottom + (S.width * S.bottom_margin);
407 int LibRaw::add_masked_borders_to_bitmap()
409 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
410 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
412 if(S.width != S.iwidth || S.height!=S.iheight)
413 return LIBRAW_CANNOT_ADDMASK;
415 if(IO.fuji_width || P1.is_foveon || !P1.filters)
416 return LIBRAW_CANNOT_ADDMASK;
418 if(!imgdata.image)
419 return LIBRAW_OUT_OF_ORDER_CALL;
421 if(S.width == S.raw_width && S.height == S.raw_height)
422 return LIBRAW_SUCCESS; // nothing to do or already called
424 ushort (*newimage)[4];
426 newimage = (ushort (*)[4]) calloc (S.raw_height*S.raw_width, sizeof (*newimage));
427 merror (newimage, "add_masked_borders_to_bitmap()");
429 int r,c;
430 // top rows
431 for (r=0; r<S.top_margin;r++)
432 for(c=0;c<S.raw_width;c++)
434 ushort *p = get_masked_pointer(r,c);
435 if(p)
436 newimage[r*S.raw_width+c][FC(r,c)] = *p;
438 // middle rows
439 for (r=S.top_margin; r<S.top_margin+S.height;r++)
441 int row = r-S.top_margin;
442 for(c=0;c<S.left_margin;c++)
444 ushort *p = get_masked_pointer(r,c);
445 if(p)
446 newimage[r*S.raw_width+c][FC(r,c)] = *p;
448 for(c=S.left_margin; c<S.left_margin+S.iwidth;c++)
450 int col = c - S.left_margin;
451 newimage[r*S.raw_width+c][FC(r,c)] = imgdata.image[row*S.iwidth+col][FC(row,col)];
453 for(c=S.left_margin+S.iwidth;c<S.raw_width;c++)
455 ushort *p = get_masked_pointer(r,c);
456 if(p)
457 newimage[r*S.raw_width+c][FC(r,c)] = *p;
460 // bottom rows
461 for (r=S.top_margin+S.height; r<S.raw_height;r++)
462 for(c=0;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;
468 free(imgdata.image);
469 imgdata.image=newimage;
470 S.iwidth = S.width = S.raw_width;
471 S.iheight = S.height = S.raw_height;
472 return LIBRAW_SUCCESS;
476 int LibRaw::open_file(const char *fname)
479 if(!fname)
480 return ENOENT;
482 recycle();
483 libraw_internal_data.internal_data.ifname = (char*)fname;
484 try {
485 if(!(ID.input = fopen(ID.ifname,"rb")))
486 return errno;
488 SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
490 if (O.use_camera_matrix < 0)
491 O.use_camera_matrix = O.use_camera_wb;
493 identify();
495 int saved_raw_width = S.raw_width;
496 int saved_width = S.width;
497 // from packed_12_load_raw
498 if ((load_raw == &LibRaw:: packed_12_load_raw) && (S.raw_width * 2 >= S.width * 3))
500 // raw_width is in bytes!
501 S.raw_width = S.raw_width * 2 / 3;
503 else if (S.pixel_aspect < 0.95 || S.pixel_aspect > 1.05)
505 S.width*=S.pixel_aspect;
508 if(S.raw_width>S.width + S.left_margin)
509 S.right_margin = S.raw_width - S.width - S.left_margin;
511 if(S.raw_height > S.height + S.top_margin)
512 S.bottom_margin = S.raw_height - S.height - S.top_margin;
514 S.raw_width = saved_raw_width;
515 S.width = saved_width;
517 if(C.profile_length)
519 if(C.profile) free(C.profile);
520 C.profile = malloc(C.profile_length);
521 merror(C.profile,"LibRaw::open_file()");
522 fseek(ID.input,ID.profile_offset,SEEK_SET);
523 fread(C.profile,C.profile_length,1,ID.input);
526 SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
528 catch ( LibRaw_exceptions err) {
529 EXCEPTION_HANDLER(err);
532 if(P1.raw_count < 1)
533 return LIBRAW_FILE_UNSUPPORTED;
535 if (O.user_flip >= 0)
536 S.flip = O.user_flip;
538 switch ((S.flip+3600) % 360)
540 case 270: S.flip = 5; break;
541 case 180: S.flip = 3; break;
542 case 90: S.flip = 6; break;
545 write_fun = &LibRaw::write_ppm_tiff;
547 if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
549 S.height += S.height & 1;
550 S.width += S.width & 1;
553 IO.shrink = P1.filters && (O.half_size || O.threshold || O.aber[0] != 1 || O.aber[2] != 1);
554 S.iheight = (S.height + IO.shrink) >> IO.shrink;
555 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
557 SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
560 return LIBRAW_SUCCESS;
563 int LibRaw::unpack(void)
565 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
566 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
567 try {
569 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
570 if (O.shot_select >= P1.raw_count)
571 return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
573 if(!load_raw)
574 return LIBRAW_UNSPECIFIED_ERROR;
576 if (O.use_camera_matrix && C.cmatrix[0][0] > 0.25)
578 memcpy (C.rgb_cam, C.cmatrix, sizeof (C.cmatrix));
579 IO.raw_color = 0;
581 // already allocated ?
582 if(imgdata.image) free(imgdata.image);
584 imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
585 merror (imgdata.image, "unpack()");
588 if(S.top_margin || S.left_margin || S.right_margin || S.bottom_margin)
590 unsigned sz = S.raw_height*(S.left_margin+S.right_margin)
591 + S.width*(S.top_margin+S.bottom_margin);
592 imgdata.masked_pixels.buffer = (ushort*) calloc(sz, sizeof(ushort));
593 init_masked_ptrs();
595 if (libraw_internal_data.unpacker_data.meta_length)
597 libraw_internal_data.internal_data.meta_data =
598 (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
599 merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
601 fseek (ID.input, libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
602 // foveon_load_raw produces different data for document_mode, we'll
603 // deal with it in dcraw_document_mode_processing
604 int save_document_mode = O.document_mode;
605 O.document_mode = 0;
607 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
608 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
610 (this->*load_raw)();
612 O.document_mode = save_document_mode;
614 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
615 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
617 SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
618 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
620 return 0;
622 catch ( LibRaw_exceptions err) {
623 EXCEPTION_HANDLER(err);
627 int LibRaw::dcraw_document_mode_processing(void)
629 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
630 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
632 try {
634 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
635 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
637 O.document_mode = 2;
638 if(P1.is_foveon)
640 // filter image data for foveon document mode
641 short *iptr = (short *)imgdata.image;
642 for (int i=0; i < S.height*S.width*4; i++)
644 if ((short) iptr[i] < 0)
645 iptr[i] = 0;
647 SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
650 O.use_fuji_rotate = 0;
651 if (!(O.filtering_mode & LIBRAW_FILTERING_NOZEROES) && IO.zero_is_bad)
653 remove_zeroes();
654 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
656 if(O.bad_pixels)
658 bad_pixels(O.bad_pixels);
659 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
661 if (O.dark_frame)
663 subtract (O.dark_frame);
664 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
666 if(O.filtering_mode & LIBRAW_FILTERING_NOBLACKS)
667 C.black=0;
669 if (O.user_black >= 0)
670 C.black = O.user_black;
672 if (O.user_sat > 0)
673 C.maximum = O.user_sat;
675 pre_interpolate();
676 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
678 if (libraw_internal_data.internal_output_params.mix_green)
680 int i;
681 for (P1.colors=3, i=0; i < S.height*S.width; i++)
682 imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
684 SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
686 if (!P1.is_foveon && P1.colors == 3)
687 median_filter();
688 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
690 if (!P1.is_foveon && O.highlight == 2)
691 blend_highlights();
693 if (!P1.is_foveon && O.highlight > 2)
694 recover_highlights();
695 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
697 if (O.use_fuji_rotate)
698 fuji_rotate();
699 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
700 #ifndef NO_LCMS
701 if(O.camera_profile)
703 apply_profile(O.camera_profile,O.output_profile);
704 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
706 #endif
707 if(!libraw_internal_data.output_data.histogram)
709 libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
710 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_document_mode_processing()");
712 convert_to_rgb();
713 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
715 if (O.use_fuji_rotate)
716 stretch();
717 SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
719 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
720 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
722 return 0;
724 catch ( LibRaw_exceptions err) {
725 EXCEPTION_HANDLER(err);
730 #if 1
731 #define FORC(cnt) for (c=0; c < cnt; c++)
732 #define FORCC FORC(ret->colors)
733 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
735 libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
737 if(!T.thumb)
739 if ( !ID.toffset)
741 if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
743 else
745 if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
747 return NULL;
750 if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
752 libraw_processed_image_t * ret =
753 (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
755 if(!ret)
757 if(errcode) *errcode= ENOMEM;
758 return NULL;
761 bzero(ret,sizeof(libraw_processed_image_t));
762 ret->type = LIBRAW_IMAGE_BITMAP;
763 ret->height = T.theight;
764 ret->width = T.twidth;
765 ret->colors = 3;
766 ret->bits = 8;
767 ret->gamma_corrected = 1;
768 ret->data_size = T.tlength;
769 memmove(ret->data,T.thumb,T.tlength);
770 if(errcode) *errcode= 0;
771 return ret;
773 else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
775 ushort exif[5];
776 int mk_exif = 0;
777 if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
779 int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
781 libraw_processed_image_t * ret =
782 (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
784 if(!ret)
786 if(errcode) *errcode= ENOMEM;
787 return NULL;
790 bzero(ret,sizeof(libraw_processed_image_t));
792 ret->type = LIBRAW_IMAGE_JPEG;
793 ret->data_size = dsize;
795 ret->data[0] = 0xff;
796 ret->data[1] = 0xd8;
797 if(mk_exif)
799 struct tiff_hdr th;
800 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
801 exif[1] = htons (8 + sizeof th);
802 memmove(ret->data+2,exif,sizeof(exif));
803 tiff_head (&th, 0);
804 memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
805 memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
807 else
809 memmove(ret->data+2,T.thumb+2,T.tlength-2);
811 if(errcode) *errcode= 0;
812 return ret;
815 else
817 if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
818 return NULL;
825 libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
827 if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE)
829 if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
830 return NULL;
833 if(!libraw_internal_data.output_data.histogram)
835 libraw_internal_data.output_data.histogram =
836 (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
837 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_make_mem_image()");
840 unsigned ds = S.height * S.width * (O.output_bps/8) * P1.colors;
841 libraw_processed_image_t *ret = (libraw_processed_image_t*)::malloc(sizeof(libraw_processed_image_t)+ds);
842 if(!ret)
844 if(errcode) *errcode= ENOMEM;
845 return NULL;
847 bzero(ret,sizeof(libraw_processed_image_t));
848 // metadata init
850 int s_iheight = S.iheight;
851 int s_iwidth = S.iwidth;
852 int s_width = S.width;
853 int s_hwight = S.height;
855 S.iheight = S.height;
856 S.iwidth = S.width;
859 if (S.flip & 4) SWAP(S.height,S.width);
862 ret->type = LIBRAW_IMAGE_BITMAP;
863 ret->height = S.height;
864 ret->width = S.width;
865 ret->colors = P1.colors;
866 ret->bits = O.output_bps;
867 ret->gamma_corrected = (O.output_bps == 8)?1:O.gamma_16bit;
869 ret->data_size = ds;
871 // Cut'n'paste from write_tiff_ppm, should be generalized later
872 uchar *bufp = ret->data;
873 uchar *ppm;
874 ushort *ppm2,lut16[0x10000];
875 int c, row, col, soff, rstep, cstep;
878 if (ret->bits == 8 || ret->gamma_corrected ) gamma_lut (lut16);
879 soff = flip_index (0, 0);
880 cstep = flip_index (0, 1) - soff;
881 rstep = flip_index (1, 0) - flip_index (0, S.width);
884 for (row=0; row < ret->height; row++, soff += rstep)
886 ppm2 = (ushort*) (ppm = bufp);
887 for (col=0; col < ret->width; col++, soff += cstep)
888 if (ret->bits == 8)
889 FORCC ppm [col*ret->colors+c] = lut16[imgdata.image[soff][c]]/256;
890 else if(ret->gamma_corrected)
891 FORCC ppm2[col*ret->colors+c] = lut16[imgdata.image[soff][c]];
892 else
893 FORCC ppm2[col*ret->colors+c] = imgdata.image[soff][c];
894 bufp+=ret->colors*(ret->bits/8)*ret->width;
896 if(errcode) *errcode= 0;
898 S.iheight = s_iheight;
899 S.iwidth = s_iwidth;
900 S.width = s_width;
901 S.height = s_hwight;
903 return ret;
906 #undef FORC
907 #undef FORCC
908 #undef SWAP
909 #endif
912 int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
914 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
916 if(!imgdata.image)
917 return LIBRAW_OUT_OF_ORDER_CALL;
919 if(!filename)
920 return ENOENT;
921 FILE *f = fopen(filename,"wb");
923 if(!f)
924 return errno;
926 try {
927 if(!libraw_internal_data.output_data.histogram)
929 libraw_internal_data.output_data.histogram =
930 (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
931 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
933 write_ppm_tiff(f);
934 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
935 fclose(f);
936 return 0;
938 catch ( LibRaw_exceptions err) {
939 fclose(f);
940 EXCEPTION_HANDLER(err);
944 void LibRaw::kodak_thumb_loader()
946 // some kodak cameras
947 ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
948 int s_colors = P1.colors;
949 unsigned s_filters = P1.filters;
950 ushort (*s_image)[4] = imgdata.image;
953 S.height = T.theight;
954 S.width = T.twidth;
955 P1.filters = 0;
957 if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw)
959 S.height += S.height & 1;
960 S.width += S.width & 1;
963 imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
964 merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
966 fseek (ID.input,ID.toffset, SEEK_SET);
967 // read kodak thumbnail into T.image[]
968 (this->*thumb_load_raw)();
970 // copy-n-paste from image pipe
971 #define MIN(a,b) ((a) < (b) ? (a) : (b))
972 #define MAX(a,b) ((a) > (b) ? (a) : (b))
973 #define LIM(x,min,max) MAX(min,MIN(x,max))
974 #define CLIP(x) LIM(x,0,65535)
975 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
977 // from scale_colors
979 double dmax;
980 float scale_mul[4];
981 int c,val;
982 for (dmax=DBL_MAX, c=0; c < 3; c++)
983 if (dmax > C.pre_mul[c])
984 dmax = C.pre_mul[c];
986 for( c=0; c< 3; c++)
987 scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
988 scale_mul[3] = scale_mul[1];
990 size_t size = S.height * S.width;
991 for (int i=0; i < size*4 ; i++)
993 val = imgdata.image[0][i];
994 if(!val) continue;
995 val *= scale_mul[i & 3];
996 imgdata.image[0][i] = CLIP(val);
1000 // from convert_to_rgb
1001 ushort *img;
1002 int row,col;
1004 int (*t_hist)[LIBRAW_HISTOGRAM_SIZE] = (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
1005 merror (t_hist, "LibRaw::kodak_thumb_loader()");
1007 float out[3],
1008 out_cam[3][4] =
1010 {2.81761312, -1.98369181, 0.166078627, 0},
1011 {-0.111855984, 1.73688626, -0.625030339, 0},
1012 {-0.0379119813, -0.891268849, 1.92918086, 0}
1015 for (img=imgdata.image[0], row=0; row < S.height; row++)
1016 for (col=0; col < S.width; col++, img+=4)
1018 out[0] = out[1] = out[2] = 0;
1019 for(int c=0;c<3;c++)
1021 out[0] += out_cam[0][c] * img[c];
1022 out[1] += out_cam[1][c] * img[c];
1023 out[2] += out_cam[2][c] * img[c];
1025 for(int c=0; c<3; c++)
1026 img[c] = CLIP((int) out[c]);
1027 for(int c=0; c<P1.colors;c++)
1028 t_hist[c][img[c] >> 3]++;
1032 // from gamma_lut
1033 int (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
1034 libraw_internal_data.output_data.histogram = t_hist;
1036 ushort *lut16 = (ushort*)calloc(0x10000,sizeof(ushort));
1037 merror(lut16,"LibRaw::kodak_thumb_loader()");
1038 gamma_lut(lut16);
1040 libraw_internal_data.output_data.histogram = save_hist;
1042 free(t_hist);
1044 // from write_ppm_tiff - copy pixels into bitmap
1046 S.iheight = S.height;
1047 S.iwidth = S.width;
1048 if (S.flip & 4) SWAP(S.height,S.width);
1050 if(T.thumb) free(T.thumb);
1051 T.thumb = (char*) calloc (S.width * S.height, P1.colors);
1052 merror (T.thumb, "LibRaw::kodak_thumb_loader()");
1053 T.tlength = S.width * S.height * P1.colors;
1055 // from write_tiff_ppm
1057 int soff = flip_index (0, 0);
1058 int cstep = flip_index (0, 1) - soff;
1059 int rstep = flip_index (1, 0) - flip_index (0, S.width);
1061 for (int row=0; row < S.height; row++, soff += rstep)
1063 char *ppm = T.thumb + row*S.width*P1.colors;
1064 for (int col=0; col < S.width; col++, soff += cstep)
1065 for(int c = 0; c < P1.colors; c++)
1066 ppm [col*P1.colors+c] = lut16[imgdata.image[soff][c]]/256;
1069 free(lut16);
1070 // restore variables
1071 free(imgdata.image);
1072 imgdata.image = s_image;
1074 T.twidth = S.width;
1075 S.width = s_width;
1077 S.iwidth = s_iwidth;
1078 S.iheight = s_iheight;
1080 T.theight = S.height;
1081 S.height = s_height;
1083 T.tcolors = P1.colors;
1084 P1.colors = s_colors;
1086 P1.filters = s_filters;
1088 #undef MIN
1089 #undef MAX
1090 #undef LIM
1091 #undef CLIP
1092 #undef SWAP
1095 void LibRaw::foveon_thumb_loader (void)
1097 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
1098 struct decode *dindex;
1099 short pred[3];
1101 if(T.thumb) free(T.thumb);
1102 T.thumb = NULL;
1104 bwide = get4();
1105 if (bwide > 0)
1107 if (bwide < T.twidth*3) return;
1108 T.thumb = (char*)malloc(3*T.twidth * T.theight);
1109 merror (T.thumb, "foveon_thumb()");
1110 char *buf = (char*)malloc(bwide);
1111 merror (buf, "foveon_thumb()");
1112 for (row=0; row < T.theight; row++)
1114 fread(buf, 1, bwide, ID.input);
1115 memmove(T.thumb+(row*T.twidth*3),buf,T.twidth*3);
1117 free(buf);
1118 T.tlength = 3*T.twidth * T.theight;
1119 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1120 return;
1122 else
1124 foveon_decoder (256, 0);
1125 T.thumb = (char*)malloc(3*T.twidth * T.theight);
1126 char *bufp = T.thumb;
1127 merror (T.thumb, "foveon_thumb()");
1128 for (row=0; row < T.theight; row++)
1130 memset (pred, 0, sizeof pred);
1131 if (!bit) get4();
1132 for (bit=col=0; col < T.twidth; col++)
1133 for(c=0;c<3;c++)
1135 for (dindex=first_decode; dindex->branch[0]; )
1137 if ((bit = (bit-1) & 31) == 31)
1138 for (i=0; i < 4; i++)
1139 bitbuf = (bitbuf << 8) + fgetc(ID.input);
1140 dindex = dindex->branch[bitbuf >> bit & 1];
1142 pred[c] += dindex->leaf;
1143 (*bufp++)=pred[c];
1146 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1147 T.tlength = 3*T.twidth * T.theight;
1149 return;
1153 // Äîñòàåò thumbnail èç ôàéëà, ñòàâèò thumb_format â ñîîòâåòñòâèè ñ ôîðìàòîì
1154 int LibRaw::unpack_thumb(void)
1156 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1157 CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
1159 try {
1160 if ( !ID.toffset)
1162 return LIBRAW_NO_THUMBNAIL;
1164 else if (thumb_load_raw)
1166 kodak_thumb_loader();
1167 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1168 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1169 return 0;
1171 else
1173 fseek (ID.input,ID.toffset, SEEK_SET);
1174 if ( write_thumb == &LibRaw::jpeg_thumb)
1176 if(T.thumb) free(T.thumb);
1177 T.thumb = (char *) malloc (T.tlength);
1178 merror (T.thumb, "jpeg_thumb()");
1179 fread (T.thumb, 1, T.tlength, ID.input);
1180 T.tcolors = 3;
1181 T.tformat = LIBRAW_THUMBNAIL_JPEG;
1182 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1183 return 0;
1185 else if (write_thumb == &LibRaw::ppm_thumb)
1187 T.tlength = T.twidth * T.theight*3;
1188 if(T.thumb) free(T.thumb);
1190 T.thumb = (char *) malloc (T.tlength);
1191 merror (T.thumb, "ppm_thumb()");
1193 fread (T.thumb, 1, T.tlength, ID.input);
1195 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1196 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1197 return 0;
1200 else if (write_thumb == &LibRaw::foveon_thumb)
1202 foveon_thumb_loader();
1203 // may return with error, so format is set in
1204 // foveon thumb loader itself
1205 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1206 return 0;
1208 // else if -- all other write_thumb cases!
1209 else
1211 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1214 // last resort
1215 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1217 catch ( LibRaw_exceptions err) {
1218 EXCEPTION_HANDLER(err);
1223 int LibRaw::dcraw_thumb_writer(const char *fname)
1225 // CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);
1227 if(!fname)
1228 return ENOENT;
1230 FILE *tfp = fopen(fname,"wb");
1232 if(!tfp)
1233 return errno;
1235 if(!T.thumb)
1237 fclose(tfp);
1238 return LIBRAW_OUT_OF_ORDER_CALL;
1241 try {
1242 switch (T.tformat)
1244 case LIBRAW_THUMBNAIL_JPEG:
1245 jpeg_thumb_writer (tfp,T.thumb,T.tlength);
1246 break;
1247 case LIBRAW_THUMBNAIL_BITMAP:
1248 fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
1249 fwrite (T.thumb, 1, T.tlength, tfp);
1250 break;
1251 default:
1252 fclose(tfp);
1253 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1255 fclose(tfp);
1256 return 0;
1258 catch ( LibRaw_exceptions err) {
1259 fclose(tfp);
1260 EXCEPTION_HANDLER(err);
1264 int LibRaw::adjust_sizes_info_only(void)
1266 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1267 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_FUJI_ROTATE);
1268 if (O.use_fuji_rotate)
1270 if (IO.fuji_width)
1272 IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
1273 S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
1274 S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
1276 else
1278 if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
1279 if (S.pixel_aspect > 1) S.iwidth = (ushort) (S.iwidth * S.pixel_aspect + 0.5);
1282 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1283 if (S.flip & 4)
1285 unsigned short t = S.iheight;
1286 S.iheight=S.iwidth;
1287 S.iwidth = t;
1288 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1290 return 0;
1293 int LibRaw::dcraw_process(void)
1295 int quality,i;
1298 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1299 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1301 try {
1303 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
1304 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
1306 if(O.half_size)
1307 O.four_color_rgb = 1;
1309 if (!(O.filtering_mode & LIBRAW_FILTERING_NOZEROES) && IO.zero_is_bad)
1311 remove_zeroes();
1312 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
1314 if(O.bad_pixels)
1316 bad_pixels(O.bad_pixels);
1317 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
1319 if (O.dark_frame)
1321 subtract (O.dark_frame);
1322 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
1325 quality = 2 + !IO.fuji_width;
1327 if(O.filtering_mode & LIBRAW_FILTERING_NOBLACKS)
1328 C.black=0;
1330 if (O.user_qual >= 0) quality = O.user_qual;
1331 if (O.user_black >= 0) C.black = O.user_black;
1332 if (O.user_sat > 0) C.maximum = O.user_sat;
1334 if (P1.is_foveon && !O.document_mode)
1336 foveon_interpolate();
1337 SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
1340 if (!P1.is_foveon && O.document_mode < 2)
1342 scale_colors();
1343 SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
1346 pre_interpolate();
1347 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1349 if (P1.filters && !O.document_mode)
1351 if (quality == 0)
1352 lin_interpolate();
1353 else if (quality == 1 || P1.colors > 3)
1354 vng_interpolate();
1355 else if (quality == 2)
1356 ppg_interpolate();
1357 else
1358 ahd_interpolate();
1359 SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
1361 if (IO.mix_green)
1363 for (P1.colors=3, i=0; i < S.height * S.width; i++)
1364 imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
1365 SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
1368 if(!P1.is_foveon)
1370 if (P1.colors == 3)
1372 median_filter();
1373 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
1376 if (O.highlight == 2)
1378 blend_highlights();
1379 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1382 if (O.highlight > 2)
1384 recover_highlights();
1385 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1388 if (O.use_fuji_rotate)
1390 fuji_rotate();
1391 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1394 if(!libraw_internal_data.output_data.histogram)
1396 libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1397 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
1399 #ifndef NO_LCMS
1400 if(O.camera_profile)
1402 apply_profile(O.camera_profile,O.output_profile);
1403 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
1405 #endif
1407 convert_to_rgb();
1408 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
1410 if (O.use_fuji_rotate)
1412 stretch();
1413 SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
1415 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
1416 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
1417 return 0;
1419 catch ( LibRaw_exceptions err) {
1420 EXCEPTION_HANDLER(err);
1424 // Supported cameras:
1425 static const char *static_camera_list[] =
1427 "Adobe Digital Negative (DNG)",
1428 "Apple QuickTake 100",
1429 "Apple QuickTake 150",
1430 "Apple QuickTake 200",
1431 "AVT F-080C",
1432 "AVT F-145C",
1433 "AVT F-201C",
1434 "AVT F-510C",
1435 "AVT F-810C",
1436 "Canon PowerShot 600",
1437 "Canon PowerShot A5",
1438 "Canon PowerShot A5 Zoom",
1439 "Canon PowerShot A50",
1440 "Canon PowerShot A460 (CHDK hack)",
1441 "Canon PowerShot A530 (CHDK hack)",
1442 "Canon PowerShot A610 (CHDK hack)",
1443 "Canon PowerShot A620 (CHDK hack)",
1444 "Canon PowerShot A630 (CHDK hack)",
1445 "Canon PowerShot A640 (CHDK hack)",
1446 "Canon PowerShot A650 (CHDK hack)",
1447 "Canon PowerShot A710 IS (CHDK hack)",
1448 "Canon PowerShot A720 IS (CHDK hack)",
1449 "Canon PowerShot Pro70",
1450 "Canon PowerShot Pro90 IS",
1451 "Canon PowerShot G1",
1452 "Canon PowerShot G2",
1453 "Canon PowerShot G3",
1454 "Canon PowerShot G5",
1455 "Canon PowerShot G6",
1456 "Canon PowerShot G7 (CHDK hack)",
1457 "Canon PowerShot G9",
1458 "Canon PowerShot G10",
1459 "Canon PowerShot S2 IS (CHDK hack)",
1460 "Canon PowerShot S3 IS (CHDK hack)",
1461 "Canon PowerShot S5 IS (CHDK hack)",
1462 "Canon PowerShot SD300 (CHDK hack)",
1463 "Canon PowerShot S30",
1464 "Canon PowerShot S40",
1465 "Canon PowerShot S45",
1466 "Canon PowerShot S50",
1467 "Canon PowerShot S60",
1468 "Canon PowerShot S70",
1469 "Canon PowerShot Pro1",
1470 "Canon EOS D30",
1471 "Canon EOS D60",
1472 "Canon EOS 5D",
1473 "Canon EOS 5D Mark II",
1474 "Canon EOS 10D",
1475 "Canon EOS 20D",
1476 "Canon EOS 30D",
1477 "Canon EOS 40D",
1478 "Canon EOS 50D",
1479 "Canon EOS 300D / Digital Rebel / Kiss Digital",
1480 "Canon EOS 350D / Digital Rebel XT / Kiss Digital N",
1481 "Canon EOS 400D / Digital Rebel XTi / Kiss Digital X",
1482 "Canon EOS 450D / Digital Rebel XSi / Kiss Digital X2",
1483 "Canon EOS 1000D / Digital Rebel XS / Kiss Digital F",
1484 "Canon EOS D2000C",
1485 "Canon EOS-1D",
1486 "Canon EOS-1DS",
1487 "Canon EOS-1D Mark II",
1488 "Canon EOS-1D Mark III",
1489 "Canon EOS-1D Mark II N",
1490 "Canon EOS-1Ds Mark II",
1491 "Canon EOS-1Ds Mark III",
1492 "Casio QV-2000UX",
1493 "Casio QV-3000EX",
1494 "Casio QV-3500EX",
1495 "Casio QV-4000",
1496 "Casio QV-5700",
1497 "Casio QV-R41",
1498 "Casio QV-R51",
1499 "Casio QV-R61",
1500 "Casio EX-S100",
1501 "Casio EX-Z4",
1502 "Casio EX-Z50",
1503 "Casio EX-Z55",
1504 "Casio Exlim Pro 505",
1505 "Casio Exlim Pro 600",
1506 "Casio Exlim Pro 700",
1507 "Contax N Digital",
1508 "Creative PC-CAM 600",
1509 "Epson R-D1",
1510 "Foculus 531C",
1511 "Fuji FinePix E550",
1512 "Fuji FinePix E900",
1513 "Fuji FinePix F700",
1514 "Fuji FinePix F710",
1515 "Fuji FinePix F800",
1516 "Fuji FinePix F810",
1517 "Fuji FinePix S2Pro",
1518 "Fuji FinePix S3Pro",
1519 "Fuji FinePix S5Pro",
1520 "Fuji FinePix S20Pro",
1521 "Fuji FinePix S100FS",
1522 "Fuji FinePix S5000",
1523 "Fuji FinePix S5100/S5500",
1524 "Fuji FinePix S5200/S5600",
1525 "Fuji FinePix S6000fd",
1526 "Fuji FinePix S7000",
1527 "Fuji FinePix S9000/S9500",
1528 "Fuji FinePix S9100/S9600",
1529 "Fuji IS-1",
1530 "Hasselblad CFV",
1531 "Hasselblad H3D",
1532 "Imacon Ixpress 16-megapixel",
1533 "Imacon Ixpress 22-megapixel",
1534 "Imacon Ixpress 39-megapixel",
1535 "ISG 2020x1520",
1536 "Kodak DC20 (see Oliver Hartman's page)",
1537 "Kodak DC25 (see Jun-ichiro Itoh's page)",
1538 "Kodak DC40",
1539 "Kodak DC50",
1540 "Kodak DC120 (also try kdc2tiff)",
1541 "Kodak DCS200",
1542 "Kodak DCS315C",
1543 "Kodak DCS330C",
1544 "Kodak DCS420",
1545 "Kodak DCS460",
1546 "Kodak DCS460A",
1547 "Kodak DCS520C",
1548 "Kodak DCS560C",
1549 "Kodak DCS620C",
1550 "Kodak DCS620X",
1551 "Kodak DCS660C",
1552 "Kodak DCS660M",
1553 "Kodak DCS720X",
1554 "Kodak DCS760C",
1555 "Kodak DCS760M",
1556 "Kodak EOSDCS1",
1557 "Kodak EOSDCS3B",
1558 "Kodak NC2000F",
1559 "Kodak ProBack",
1560 "Kodak PB645C",
1561 "Kodak PB645H",
1562 "Kodak PB645M",
1563 "Kodak DCS Pro 14n",
1564 "Kodak DCS Pro 14nx",
1565 "Kodak DCS Pro SLR/c",
1566 "Kodak DCS Pro SLR/n",
1567 "Kodak C330",
1568 "Kodak C603",
1569 "Kodak P850",
1570 "Kodak P880",
1571 "Kodak KAI-0340",
1572 "Konica KD-400Z",
1573 "Konica KD-510Z",
1574 "Leaf AFi 7",
1575 "Leaf Aptus 17",
1576 "Leaf Aptus 22",
1577 "Leaf Aptus 54S",
1578 "Leaf Aptus 65",
1579 "Leaf Aptus 75",
1580 "Leaf Aptus 75S",
1581 "Leaf Cantare",
1582 "Leaf CatchLight",
1583 "Leaf CMost",
1584 "Leaf DCB2",
1585 "Leaf Valeo 6",
1586 "Leaf Valeo 11",
1587 "Leaf Valeo 17",
1588 "Leaf Valeo 22",
1589 "Leaf Volare",
1590 "Leica Digilux 2",
1591 "Leica Digilux 3",
1592 "Leica D-LUX2",
1593 "Leica D-LUX3",
1594 "Leica D-LUX4",
1595 "Leica V-LUX1",
1596 "Logitech Fotoman Pixtura",
1597 "Mamiya ZD",
1598 "Micron 2010",
1599 "Minolta RD175",
1600 "Minolta DiMAGE 5",
1601 "Minolta DiMAGE 7",
1602 "Minolta DiMAGE 7i",
1603 "Minolta DiMAGE 7Hi",
1604 "Minolta DiMAGE A1",
1605 "Minolta DiMAGE A2",
1606 "Minolta DiMAGE A200",
1607 "Minolta DiMAGE G400",
1608 "Minolta DiMAGE G500",
1609 "Minolta DiMAGE G530",
1610 "Minolta DiMAGE G600",
1611 "Minolta DiMAGE Z2",
1612 "Minolta Alpha/Dynax/Maxxum 5D",
1613 "Minolta Alpha/Dynax/Maxxum 7D",
1614 "Nikon D1",
1615 "Nikon D1H",
1616 "Nikon D1X",
1617 "Nikon D2H",
1618 "Nikon D2Hs",
1619 "Nikon D2X",
1620 "Nikon D2Xs",
1621 "Nikon D3",
1622 "Nikon D40",
1623 "Nikon D40X",
1624 "Nikon D50",
1625 "Nikon D60",
1626 "Nikon D70",
1627 "Nikon D70s",
1628 "Nikon D80",
1629 "Nikon D90",
1630 "Nikon D100",
1631 "Nikon D200",
1632 "Nikon D300",
1633 "Nikon D700",
1634 "Nikon E700 (\"DIAG RAW\" hack)",
1635 "Nikon E800 (\"DIAG RAW\" hack)",
1636 "Nikon E880 (\"DIAG RAW\" hack)",
1637 "Nikon E900 (\"DIAG RAW\" hack)",
1638 "Nikon E950 (\"DIAG RAW\" hack)",
1639 "Nikon E990 (\"DIAG RAW\" hack)",
1640 "Nikon E995 (\"DIAG RAW\" hack)",
1641 "Nikon E2100 (\"DIAG RAW\" hack)",
1642 "Nikon E2500 (\"DIAG RAW\" hack)",
1643 "Nikon E3200 (\"DIAG RAW\" hack)",
1644 "Nikon E3700 (\"DIAG RAW\" hack)",
1645 "Nikon E4300 (\"DIAG RAW\" hack)",
1646 "Nikon E4500 (\"DIAG RAW\" hack)",
1647 "Nikon E5000",
1648 "Nikon E5400",
1649 "Nikon E5700",
1650 "Nikon E8400",
1651 "Nikon E8700",
1652 "Nikon E8800",
1653 "Nikon Coolpix P6000",
1654 "Nikon Coolpix S6 (\"DIAG RAW\" hack)",
1655 "Nokia N95",
1656 "Olympus C3030Z",
1657 "Olympus C5050Z",
1658 "Olympus C5060WZ",
1659 "Olympus C7070WZ",
1660 "Olympus C70Z,C7000Z",
1661 "Olympus C740UZ",
1662 "Olympus C770UZ",
1663 "Olympus C8080WZ",
1664 "Olympus E-1",
1665 "Olympus E-3",
1666 "Olympus E-10",
1667 "Olympus E-20",
1668 "Olympus E-300",
1669 "Olympus E-330",
1670 "Olympus E-400",
1671 "Olympus E-410",
1672 "Olympus E-420",
1673 "Olympus E-500",
1674 "Olympus E-510",
1675 "Olympus E-520",
1676 "Olympus SP310",
1677 "Olympus SP320",
1678 "Olympus SP350",
1679 "Olympus SP500UZ",
1680 "Olympus SP510UZ",
1681 "Olympus SP550UZ",
1682 "Olympus SP560UZ",
1683 "Panasonic DMC-FZ8",
1684 "Panasonic DMC-FZ18",
1685 "Panasonic DMC-FZ28",
1686 "Panasonic DMC-FZ30",
1687 "Panasonic DMC-FZ50",
1688 "Panasonic DMC-FX150",
1689 "Panasonic DMC-G1",
1690 "Panasonic DMC-L1",
1691 "Panasonic DMC-L10",
1692 "Panasonic DMC-LC1",
1693 "Panasonic DMC-LX1",
1694 "Panasonic DMC-LX2",
1695 "Panasonic DMC-LX3",
1696 "Pentax *ist D",
1697 "Pentax *ist DL",
1698 "Pentax *ist DL2",
1699 "Pentax *ist DS",
1700 "Pentax *ist DS2",
1701 "Pentax K10D",
1702 "Pentax K20D",
1703 "Pentax K100D",
1704 "Pentax K100D Super",
1705 "Pentax K200D",
1706 "Pentax Optio S",
1707 "Pentax Optio S4",
1708 "Pentax Optio 33WR",
1709 "Pentax Optio 750Z",
1710 "Phase One LightPhase",
1711 "Phase One H 10",
1712 "Phase One H 20",
1713 "Phase One H 25",
1714 "Phase One P 20",
1715 "Phase One P 25",
1716 "Phase One P 30",
1717 "Phase One P 45",
1718 "Pixelink A782",
1719 "Polaroid x530",
1720 "Rollei d530flex",
1721 "RoverShot 3320af",
1722 "Samsung GX-1S",
1723 "Samsung GX-10",
1724 "Sarnoff 4096x5440",
1725 "Sigma SD9",
1726 "Sigma SD10",
1727 "Sigma SD14",
1728 "Sinar 3072x2048",
1729 "Sinar 4080x4080",
1730 "Sinar 4080x5440",
1731 "Sinar STI format",
1732 "SMaL Ultra-Pocket 3",
1733 "SMaL Ultra-Pocket 4",
1734 "SMaL Ultra-Pocket 5",
1735 "Sony DSC-F828",
1736 "Sony DSC-R1",
1737 "Sony DSC-V3",
1738 "Sony DSLR-A100",
1739 "Sony DSLR-A200",
1740 "Sony DSLR-A300",
1741 "Sony DSLR-A350",
1742 "Sony DSLR-A700",
1743 "Sony DSLR-A900",
1744 "Sony XCD-SX910CR",
1745 "STV680 VGA",
1746 NULL
1749 const char** LibRaw::cameraList() { return static_camera_list;}
1750 int LibRaw::cameraCount() { return (sizeof(static_camera_list)/sizeof(static_camera_list[0]))-1; }
1753 const char * LibRaw::strprogress(enum LibRaw_progress p)
1755 switch(p)
1757 case LIBRAW_PROGRESS_START:
1758 return "Starting";
1759 case LIBRAW_PROGRESS_OPEN :
1760 return "Opening file";
1761 case LIBRAW_PROGRESS_IDENTIFY :
1762 return "Reading metadata";
1763 case LIBRAW_PROGRESS_SIZE_ADJUST:
1764 return "Adjusting size";
1765 case LIBRAW_PROGRESS_LOAD_RAW:
1766 return "Reading RAW data";
1767 case LIBRAW_PROGRESS_REMOVE_ZEROES:
1768 return "Clearing zero values";
1769 case LIBRAW_PROGRESS_BAD_PIXELS :
1770 return "Removing dead pixels";
1771 case LIBRAW_PROGRESS_DARK_FRAME:
1772 return "Subtracting dark frame data";
1773 case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
1774 return "Interpolating Foveon sensor data";
1775 case LIBRAW_PROGRESS_SCALE_COLORS:
1776 return "Scaling colors";
1777 case LIBRAW_PROGRESS_PRE_INTERPOLATE:
1778 return "Pre-interpolating";
1779 case LIBRAW_PROGRESS_INTERPOLATE:
1780 return "Interpolating";
1781 case LIBRAW_PROGRESS_MIX_GREEN :
1782 return "Mixing green channels";
1783 case LIBRAW_PROGRESS_MEDIAN_FILTER :
1784 return "Median filter";
1785 case LIBRAW_PROGRESS_HIGHLIGHTS:
1786 return "Highlight recovery";
1787 case LIBRAW_PROGRESS_FUJI_ROTATE :
1788 return "Rotating Fuji diagonal data";
1789 case LIBRAW_PROGRESS_FLIP :
1790 return "Flipping image";
1791 case LIBRAW_PROGRESS_APPLY_PROFILE:
1792 return "ICC conversion";
1793 case LIBRAW_PROGRESS_CONVERT_RGB:
1794 return "Converting to RGB";
1795 case LIBRAW_PROGRESS_STRETCH:
1796 return "Stretching image";
1797 case LIBRAW_PROGRESS_THUMB_LOAD:
1798 return "Loading thumbnail";
1799 default:
1800 return "Some strange things";