3 * Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
4 * Created: Sat Mar 8 , 2008
6 * LibRaw C++ interface (implementation)
13 #include <netinet/in.h>
17 #define LIBRAW_LIBRARY_BUILD
18 #include "libraw/libraw.h"
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
)
32 fprintf (stderr
,"%s: Unexpected end of file\n", file
);
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
;
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";
62 return "Input/output error";
63 case LIBRAW_CANCELLED_BY_CALLBACK
:
64 return "Cancelled by user callback";
66 return "Unknown error code";
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); \
97 case LIBRAW_EXCEPTION_ALLOC: \
99 return LIBRAW_UNSUFFICIENT_MEMORY; \
100 case LIBRAW_EXCEPTION_DECODE_RAW: \
101 case LIBRAW_EXCEPTION_DECODE_JPEG: \
103 return LIBRAW_DATA_ERROR; \
104 case LIBRAW_EXCEPTION_IO_EOF: \
105 case LIBRAW_EXCEPTION_IO_CORRUPT: \
107 return LIBRAW_IO_ERROR; \
108 case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK: \
110 return LIBRAW_CANCELLED_BY_CALLBACK; \
112 return LIBRAW_UNSPECIFIED_ERROR; \
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
;
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
};
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
;
169 void* LibRaw:: malloc(size_t t
)
171 void *p
= memmgr
.malloc(t
);
174 void* LibRaw:: calloc(size_t n
,size_t t
)
176 void *p
= memmgr
.calloc(n
,t
);
179 void LibRaw:: free(void *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)
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
);
226 bzero(&imgdata
.masked_pixels
,sizeof(imgdata
.masked_pixels
));
227 bzero(&imgdata
.sizes
,sizeof(imgdata
.sizes
));
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));
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()";
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()";
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()";
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()";
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()";
300 return "Unknown unpack function";
304 void LibRaw:: merror (void *ptr
, const char *where
)
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
)
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
]);
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
)
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
];
355 return NULL
; // out of bounds
357 else if (row
< S
.raw_height
)
359 int irow
= row
- S
.top_margin
- S
.height
;
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
];
376 return NULL
; // out of bounds
387 void LibRaw:: init_masked_ptrs()
389 if(!M
.buffer
) return;
393 M
.top
= M
.tl
+(S
.top_margin
*S
.left_margin
);
394 M
.tr
= M
.top
+ (S
.top_margin
*S
.width
);
397 M
.left
= M
.tr
+ (S
.top_margin
* S
.right_margin
);
398 M
.right
= M
.left
+ (S
.left_margin
* S
.height
);
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
;
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()");
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
);
436 newimage
[r
*S
.raw_width
+c
][FC(r
,c
)] = *p
;
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
);
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
);
457 newimage
[r
*S
.raw_width
+c
][FC(r
,c
)] = *p
;
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
);
466 newimage
[r
*S
.raw_width
+c
][FC(r
,c
)] = *p
;
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
)
483 libraw_internal_data
.internal_data
.ifname
= (char*)fname
;
485 if(!(ID
.input
= fopen(ID
.ifname
,"rb")))
488 SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN
);
490 if (O
.use_camera_matrix
< 0)
491 O
.use_camera_matrix
= O
.use_camera_wb
;
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
;
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
);
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
);
569 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW
,0,2);
570 if (O
.shot_select
>= P1
.raw_count
)
571 return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE
;
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
));
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
));
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
;
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
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);
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
);
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
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)
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
)
654 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES
);
658 bad_pixels(O
.bad_pixels
);
659 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS
);
663 subtract (O
.dark_frame
);
664 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME
);
666 if(O
.filtering_mode
& LIBRAW_FILTERING_NOBLACKS
)
669 if (O
.user_black
>= 0)
670 C
.black
= O
.user_black
;
673 C
.maximum
= O
.user_sat
;
676 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE
);
678 if (libraw_internal_data
.internal_output_params
.mix_green
)
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)
688 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER
);
690 if (!P1
.is_foveon
&& O
.highlight
== 2)
693 if (!P1
.is_foveon
&& O
.highlight
> 2)
694 recover_highlights();
695 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS
);
697 if (O
.use_fuji_rotate
)
699 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE
);
703 apply_profile(O
.camera_profile
,O
.output_profile
);
704 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE
);
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()");
713 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB
);
715 if (O
.use_fuji_rotate
)
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
724 catch ( LibRaw_exceptions err
) {
725 EXCEPTION_HANDLER(err
);
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
)
741 if(errcode
) *errcode
= LIBRAW_NO_THUMBNAIL
;
745 if(errcode
) *errcode
= LIBRAW_OUT_OF_ORDER_CALL
;
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
);
757 if(errcode
) *errcode
= ENOMEM
;
761 bzero(ret
,sizeof(libraw_processed_image_t
));
762 ret
->type
= LIBRAW_IMAGE_BITMAP
;
763 ret
->height
= T
.theight
;
764 ret
->width
= T
.twidth
;
767 ret
->gamma_corrected
= 1;
768 ret
->data_size
= T
.tlength
;
769 memmove(ret
->data
,T
.thumb
,T
.tlength
);
770 if(errcode
) *errcode
= 0;
773 else if (T
.tformat
== LIBRAW_THUMBNAIL_JPEG
)
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
);
786 if(errcode
) *errcode
= ENOMEM
;
790 bzero(ret
,sizeof(libraw_processed_image_t
));
792 ret
->type
= LIBRAW_IMAGE_JPEG
;
793 ret
->data_size
= dsize
;
800 memcpy (exif
, "\xff\xe1 Exif\0\0", 10);
801 exif
[1] = htons (8 + sizeof th
);
802 memmove(ret
->data
+2,exif
,sizeof(exif
));
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);
809 memmove(ret
->data
+2,T
.thumb
+2,T
.tlength
-2);
811 if(errcode
) *errcode
= 0;
817 if(errcode
) *errcode
= LIBRAW_UNSUPPORTED_THUMBNAIL
;
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
;
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
);
844 if(errcode
) *errcode
= ENOMEM
;
847 bzero(ret
,sizeof(libraw_processed_image_t
));
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
;
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
;
871 // Cut'n'paste from write_tiff_ppm, should be generalized later
872 uchar
*bufp
= ret
->data
;
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
)
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
]];
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
;
912 int LibRaw::dcraw_ppm_tiff_writer(const char *filename
)
914 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW
);
917 return LIBRAW_OUT_OF_ORDER_CALL
;
921 FILE *f
= fopen(filename
,"wb");
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()");
934 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP
);
938 catch ( LibRaw_exceptions err
) {
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
;
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); }
982 for (dmax
=DBL_MAX
, c
=0; c
< 3; c
++)
983 if (dmax
> C
.pre_mul
[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
];
995 val
*= scale_mul
[i
& 3];
996 imgdata
.image
[0][i
] = CLIP(val
);
1000 // from convert_to_rgb
1004 int (*t_hist
)[LIBRAW_HISTOGRAM_SIZE
] = (int (*)[LIBRAW_HISTOGRAM_SIZE
]) calloc(sizeof(*t_hist
),4);
1005 merror (t_hist
, "LibRaw::kodak_thumb_loader()");
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]++;
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()");
1040 libraw_internal_data
.output_data
.histogram
= save_hist
;
1044 // from write_ppm_tiff - copy pixels into bitmap
1046 S
.iheight
= S
.height
;
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;
1070 // restore variables
1071 free(imgdata
.image
);
1072 imgdata
.image
= s_image
;
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
;
1095 void LibRaw::foveon_thumb_loader (void)
1097 unsigned bwide
, row
, col
, bitbuf
=0, bit
=1, c
, i
;
1098 struct decode
*dindex
;
1101 if(T
.thumb
) free(T
.thumb
);
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);
1118 T
.tlength
= 3*T
.twidth
* T
.theight
;
1119 T
.tformat
= LIBRAW_THUMBNAIL_BITMAP
;
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
);
1132 for (bit
=col
=0; col
< T
.twidth
; col
++)
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
;
1146 T
.tformat
= LIBRAW_THUMBNAIL_BITMAP
;
1147 T
.tlength
= 3*T
.twidth
* T
.theight
;
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
);
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
);
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
);
1181 T
.tformat
= LIBRAW_THUMBNAIL_JPEG
;
1182 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD
);
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
);
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
);
1208 // else if -- all other write_thumb cases!
1211 return LIBRAW_UNSUPPORTED_THUMBNAIL
;
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);
1230 FILE *tfp
= fopen(fname
,"wb");
1238 return LIBRAW_OUT_OF_ORDER_CALL
;
1244 case LIBRAW_THUMBNAIL_JPEG
:
1245 jpeg_thumb_writer (tfp
,T
.thumb
,T
.tlength
);
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
);
1253 return LIBRAW_UNSUPPORTED_THUMBNAIL
;
1258 catch ( LibRaw_exceptions err
) {
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
)
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));
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
);
1285 unsigned short t
= S
.iheight
;
1288 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP
);
1293 int LibRaw::dcraw_process(void)
1298 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW
);
1299 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE
);
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
1307 O
.four_color_rgb
= 1;
1309 if (!(O
.filtering_mode
& LIBRAW_FILTERING_NOZEROES
) && IO
.zero_is_bad
)
1312 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES
);
1316 bad_pixels(O
.bad_pixels
);
1317 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS
);
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
)
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)
1343 SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS
);
1347 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE
);
1349 if (P1
.filters
&& !O
.document_mode
)
1353 else if (quality
== 1 || P1
.colors
> 3)
1355 else if (quality
== 2)
1359 SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE
);
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
);
1373 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER
);
1376 if (O
.highlight
== 2)
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
)
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()");
1400 if(O
.camera_profile
)
1402 apply_profile(O
.camera_profile
,O
.output_profile
);
1403 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE
);
1408 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB
);
1410 if (O
.use_fuji_rotate
)
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
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",
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",
1473 "Canon EOS 5D Mark II",
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",
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",
1504 "Casio Exlim Pro 505",
1505 "Casio Exlim Pro 600",
1506 "Casio Exlim Pro 700",
1508 "Creative PC-CAM 600",
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",
1532 "Imacon Ixpress 16-megapixel",
1533 "Imacon Ixpress 22-megapixel",
1534 "Imacon Ixpress 39-megapixel",
1536 "Kodak DC20 (see Oliver Hartman's page)",
1537 "Kodak DC25 (see Jun-ichiro Itoh's page)",
1540 "Kodak DC120 (also try kdc2tiff)",
1563 "Kodak DCS Pro 14n",
1564 "Kodak DCS Pro 14nx",
1565 "Kodak DCS Pro SLR/c",
1566 "Kodak DCS Pro SLR/n",
1596 "Logitech Fotoman Pixtura",
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",
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)",
1653 "Nikon Coolpix P6000",
1654 "Nikon Coolpix S6 (\"DIAG RAW\" hack)",
1660 "Olympus C70Z,C7000Z",
1683 "Panasonic DMC-FZ8",
1684 "Panasonic DMC-FZ18",
1685 "Panasonic DMC-FZ28",
1686 "Panasonic DMC-FZ30",
1687 "Panasonic DMC-FZ50",
1688 "Panasonic DMC-FX150",
1691 "Panasonic DMC-L10",
1692 "Panasonic DMC-LC1",
1693 "Panasonic DMC-LX1",
1694 "Panasonic DMC-LX2",
1695 "Panasonic DMC-LX3",
1704 "Pentax K100D Super",
1708 "Pentax Optio 33WR",
1709 "Pentax Optio 750Z",
1710 "Phase One LightPhase",
1724 "Sarnoff 4096x5440",
1732 "SMaL Ultra-Pocket 3",
1733 "SMaL Ultra-Pocket 4",
1734 "SMaL Ultra-Pocket 5",
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
)
1757 case LIBRAW_PROGRESS_START
:
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";
1800 return "Some strange things";