libkdcraw from trunk : update internal libraw to 0.7.0-beta1
[kdegraphics.git] / libs / libkdcraw / libraw / src / libraw_cxx.cpp
blob75053b549fe4567d7f682516f9a737b2319bfa1a
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 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 && libraw_internal_data.internal_data.input_internal)
213 delete libraw_internal_data.internal_data.input;
214 libraw_internal_data.internal_data.input = NULL;
216 libraw_internal_data.internal_data.input_internal = 0;
217 #define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
219 FREE(imgdata.image);
220 FREE(imgdata.thumbnail.thumb);
221 FREE(libraw_internal_data.internal_data.meta_data);
222 FREE(libraw_internal_data.output_data.histogram);
223 FREE(libraw_internal_data.output_data.oprof);
224 FREE(imgdata.color.profile);
225 FREE(imgdata.masked_pixels.buffer);
226 FREE(imgdata.masked_pixels.ph1_black);
227 #undef FREE
228 #define ZERO(a) bzero(&a,sizeof(a))
229 ZERO(imgdata.masked_pixels);
230 ZERO(imgdata.sizes);
231 ZERO(libraw_internal_data.internal_output_params);
232 #undef ZERO
233 memmgr.cleanup();
234 imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
235 imgdata.progress_flags = 0;
237 tls->init();
240 const char * LibRaw::unpack_function_name()
242 if(!load_raw) return "Function not set";
244 // sorted names order
245 if (load_raw == &LibRaw::adobe_dng_load_raw_lj) return "adobe_dng_load_raw_lj()";
246 if (load_raw == &LibRaw::adobe_dng_load_raw_nc) return "adobe_dng_load_raw_nc()";
247 if (load_raw == &LibRaw::canon_600_load_raw) return "canon_600_load_raw()";
249 if (load_raw == &LibRaw::canon_a5_load_raw) return "canon_a5_load_raw()";
250 if (load_raw == &LibRaw::canon_compressed_load_raw) return "canon_compressed_load_raw()";
251 if (load_raw == &LibRaw::canon_sraw_load_raw) return "canon_sraw_load_raw()";
253 if (load_raw == &LibRaw::casio_qv5700_load_raw ) return "casio_qv5700_load_raw()";
254 if (load_raw == &LibRaw::eight_bit_load_raw ) return "eight_bit_load_raw()";
255 if (load_raw == &LibRaw::foveon_load_raw ) return "foveon_load_raw()";
256 if (load_raw == &LibRaw::fuji_load_raw ) return "fuji_load_raw()";
257 // 10
258 if (load_raw == &LibRaw::hasselblad_load_raw ) return "hasselblad_load_raw()";
259 if (load_raw == &LibRaw::imacon_full_load_raw ) return "imacon_full_load_raw()";
260 if (load_raw == &LibRaw::kodak_262_load_raw ) return "kodak_262_load_raw()";
262 if (load_raw == &LibRaw::kodak_65000_load_raw ) return "kodak_65000_load_raw()";
263 if (load_raw == &LibRaw::kodak_dc120_load_raw ) return "kodak_dc120_load_raw()";
264 if (load_raw == &LibRaw::kodak_jpeg_load_raw ) return "kodak_jpeg_load_raw()";
266 if (load_raw == &LibRaw::kodak_radc_load_raw ) return "kodak_radc_load_raw()";
267 if (load_raw == &LibRaw::kodak_rgb_load_raw ) return "kodak_rgb_load_raw()";
268 if (load_raw == &LibRaw::kodak_yrgb_load_raw ) return "kodak_yrgb_load_raw()";
269 if (load_raw == &LibRaw::kodak_ycbcr_load_raw ) return "kodak_ycbcr_load_raw()";
270 // 20
271 if (load_raw == &LibRaw::leaf_hdr_load_raw ) return "leaf_hdr_load_raw()";
272 if (load_raw == &LibRaw::lossless_jpeg_load_raw) return "lossless_jpeg_load_raw()";
273 if (load_raw == &LibRaw::minolta_rd175_load_raw ) return "minolta_rd175_load_raw()";
275 if (load_raw == &LibRaw::nikon_compressed_load_raw) return "nikon_compressed_load_raw()";
276 if (load_raw == &LibRaw::nikon_e900_load_raw ) return "nikon_e900_load_raw()";
277 if (load_raw == &LibRaw::nokia_load_raw ) return "nokia_load_raw()";
279 if (load_raw == &LibRaw::olympus_e300_load_raw ) return "olympus_e300_load_raw()";
280 if (load_raw == &LibRaw::olympus_e410_load_raw ) return "olympus_e410_load_raw()";
281 if (load_raw == &LibRaw::packed_12_load_raw ) return "packed_12_load_raw()";
282 if (load_raw == &LibRaw::panasonic_load_raw ) return "panasonic_load_raw()";
283 // 30
284 if (load_raw == &LibRaw::pentax_k10_load_raw ) return "pentax_k10_load_raw()";
285 if (load_raw == &LibRaw::phase_one_load_raw ) return "phase_one_load_raw()";
286 if (load_raw == &LibRaw::phase_one_load_raw_c ) return "phase_one_load_raw_c()";
288 if (load_raw == &LibRaw::quicktake_100_load_raw ) return "quicktake_100_load_raw()";
289 if (load_raw == &LibRaw::rollei_load_raw ) return "rollei_load_raw()";
290 if (load_raw == &LibRaw::sinar_4shot_load_raw ) return "sinar_4shot_load_raw()";
292 if (load_raw == &LibRaw::smal_v6_load_raw ) return "smal_v6_load_raw()";
293 if (load_raw == &LibRaw::smal_v9_load_raw ) return "smal_v9_load_raw()";
294 if (load_raw == &LibRaw::sony_load_raw ) return "sony_load_raw()";
295 if (load_raw == &LibRaw::sony_arw_load_raw ) return "sony_arw_load_raw()";
296 // 40
297 if (load_raw == &LibRaw::sony_arw2_load_raw ) return "sony_arw2_load_raw()";
298 if (load_raw == &LibRaw::unpacked_load_raw ) return "unpacked_load_raw()";
299 // 42 total
301 return "Unknown unpack function";
305 void LibRaw:: merror (void *ptr, const char *where)
307 if (ptr) return;
308 if(callbacks.mem_cb)(*callbacks.mem_cb)(callbacks.memcb_data,
309 libraw_internal_data.internal_data.input
310 ?libraw_internal_data.internal_data.input->fname()
311 :NULL,
312 where);
313 throw LIBRAW_EXCEPTION_ALLOC;
316 ushort * LibRaw::get_masked_pointer(int row, int col)
318 if(row<0 || col < 0) return NULL;
319 if(!M.buffer) return NULL;
320 if(row < S.top_margin)
322 // top band
323 if(col < S.left_margin)
325 return &(M.tl[row*S.left_margin+col]);
327 else if (col < S.left_margin + S.width)
329 int icol = col - S.left_margin;
330 return &(M.top[row*S.width+icol]);
332 else if (col < S.raw_width)
334 int icol = col - S.left_margin - S.width;
335 return &(M.tr[row*S.right_margin+icol]);
337 else
338 return NULL; // out of bounds
340 else if (row < S.top_margin + S.height)
342 //normal image height
343 int irow = row - S.top_margin;
344 if(col < S.left_margin)
346 return &M.left[irow*S.left_margin + col];
348 else if (col < S.left_margin + S.width)
350 // central image
351 return NULL;
353 else if (col < S.raw_width)
355 int icol = col - S.left_margin - S.width;
356 return &M.right[irow*S.right_margin+icol];
358 else
359 return NULL; // out of bounds
361 else if (row < S.raw_height)
363 int irow = row - S.top_margin - S.height;
364 // bottom band
365 if(col < S.left_margin)
367 return &M.bl[irow*S.left_margin+col];
369 else if (col < S.left_margin + S.width)
371 int icol = col - S.left_margin;
372 return &M.bottom[irow*S.width + icol];
374 else if (col < S.raw_width)
376 int icol = col - S.left_margin - S.width;
377 return &M.br[irow*S.right_margin + icol];
379 else
380 return NULL; // out of bounds
382 else
384 // out of bounds
385 return NULL;
387 // fallback
388 return NULL;
391 void LibRaw:: init_masked_ptrs()
393 if(!M.buffer) return;
395 // top band
396 M.tl = M.buffer;
397 M.top = M.tl +(S.top_margin*S.left_margin);
398 M.tr = M.top + (S.top_margin*S.width);
400 // left-right
401 M.left = M.tr + (S.top_margin * S.right_margin);
402 M.right = M.left + (S.left_margin * S.height);
404 // bottom band
405 M.bl = M.right + (S.right_margin * S.height);
406 M.bottom = M.bl + (S.left_margin * S.bottom_margin);
407 M.br = M.bottom + (S.width * S.bottom_margin);
411 int LibRaw::add_masked_borders_to_bitmap()
413 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
414 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
416 if(S.width != S.iwidth || S.height!=S.iheight)
417 return LIBRAW_CANNOT_ADDMASK;
419 if(P1.is_foveon || !P1.filters)
420 return LIBRAW_CANNOT_ADDMASK;
422 if(!imgdata.image)
423 return LIBRAW_OUT_OF_ORDER_CALL;
425 if(S.raw_width < S.width || S.raw_height < S.height)
426 return LIBRAW_SUCCESS; // nothing to do or already called
428 if(S.width == S.raw_width && S.height == S.raw_height)
429 return LIBRAW_SUCCESS; // nothing to do or already called
431 ushort (*newimage)[4];
433 newimage = (ushort (*)[4]) calloc (S.raw_height*S.raw_width, sizeof (*newimage));
434 merror (newimage, "add_masked_borders_to_bitmap()");
436 int r,c;
437 // top rows
438 for (r=0; r<S.top_margin;r++)
439 for(c=0;c<S.raw_width;c++)
441 ushort *p = get_masked_pointer(r,c);
442 if(p)
443 newimage[r*S.raw_width+c][FC(r,c)] = *p;
445 // middle rows
446 for (r=S.top_margin; r<S.top_margin+S.height;r++)
448 int row = r-S.top_margin;
449 for(c=0;c<S.left_margin;c++)
451 ushort *p = get_masked_pointer(r,c);
452 if(p)
453 newimage[r*S.raw_width+c][FC(r,c)] = *p;
455 for(c=S.left_margin; c<S.left_margin+S.iwidth;c++)
457 int col = c - S.left_margin;
458 newimage[r*S.raw_width+c][FC(r,c)] = imgdata.image[row*S.iwidth+col][FC(row,col)];
460 for(c=S.left_margin+S.iwidth;c<S.raw_width;c++)
462 ushort *p = get_masked_pointer(r,c);
463 if(p)
464 newimage[r*S.raw_width+c][FC(r,c)] = *p;
467 // bottom rows
468 for (r=S.top_margin+S.height; r<S.raw_height;r++)
469 for(c=0;c<S.raw_width;c++)
471 ushort *p = get_masked_pointer(r,c);
472 if(p)
473 newimage[r*S.raw_width+c][FC(r,c)] = *p;
475 free(imgdata.image);
476 imgdata.image=newimage;
477 S.iwidth = S.width = S.raw_width;
478 S.iheight = S.height = S.raw_height;
479 return LIBRAW_SUCCESS;
482 int LibRaw::open_file(const char *fname)
484 // this stream will close on recycle()
485 LibRaw_file_datastream *stream = new LibRaw_file_datastream(fname);
486 if(!stream->valid())
488 delete stream;
489 return LIBRAW_IO_ERROR;
491 ID.input_internal = 0; // preserve from deletion on error
492 int ret = open_datastream(stream);
493 if (ret == LIBRAW_SUCCESS)
495 ID.input_internal =1 ; // flag to delete datastream on recycle
497 else
499 delete stream;
500 ID.input_internal = 0;
502 return ret;
505 int LibRaw::open_buffer(void *buffer, size_t size)
507 // this stream will close on recycle()
508 if(!buffer || buffer==(void*)-1)
509 return LIBRAW_IO_ERROR;
511 LibRaw_buffer_datastream *stream = new LibRaw_buffer_datastream(buffer,size);
512 if(!stream->valid())
514 delete stream;
515 return LIBRAW_IO_ERROR;
517 ID.input_internal = 0; // preserve from deletion on error
518 int ret = open_datastream(stream);
519 if (ret == LIBRAW_SUCCESS)
521 ID.input_internal =1 ; // flag to delete datastream on recycle
523 else
525 delete stream;
526 ID.input_internal = 0;
528 return ret;
532 int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
535 if(!stream)
536 return ENOENT;
537 if(!stream->valid())
538 return LIBRAW_IO_ERROR;
539 recycle();
541 try {
542 ID.input = stream;
543 SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
545 if (O.use_camera_matrix < 0)
546 O.use_camera_matrix = O.use_camera_wb;
548 identify();
550 if(IO.fuji_width)
552 IO.fwidth = S.width;
553 IO.fheight = S.height;
554 S.iwidth = S.width = IO.fuji_width << !libraw_internal_data.unpacker_data.fuji_layout;
555 S.iheight = S.height = S.raw_height;
556 S.raw_height += 2*S.top_margin;
559 int saved_raw_width = S.raw_width;
560 int saved_width = S.width;
561 // from packed_12_load_raw
562 if ((load_raw == &LibRaw:: packed_12_load_raw) && (S.raw_width * 2 >= S.width * 3))
564 // raw_width is in bytes!
565 S.raw_width = S.raw_width * 2 / 3;
567 else if (S.pixel_aspect < 0.95 || S.pixel_aspect > 1.05)
569 S.width*=S.pixel_aspect;
572 if(S.raw_width>S.width + S.left_margin)
573 S.right_margin = S.raw_width - S.width - S.left_margin;
575 if(S.raw_height > S.height + S.top_margin)
576 S.bottom_margin = S.raw_height - S.height - S.top_margin;
578 S.raw_width = saved_raw_width;
579 S.width = saved_width;
581 if(C.profile_length)
583 if(C.profile) free(C.profile);
584 C.profile = malloc(C.profile_length);
585 merror(C.profile,"LibRaw::open_file()");
586 ID.input->seek(ID.profile_offset,SEEK_SET);
587 ID.input->read(C.profile,C.profile_length,1);
590 SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
592 catch ( LibRaw_exceptions err) {
593 EXCEPTION_HANDLER(err);
596 if(P1.raw_count < 1)
597 return LIBRAW_FILE_UNSUPPORTED;
599 if (O.user_flip >= 0)
600 S.flip = O.user_flip;
602 switch ((S.flip+3600) % 360)
604 case 270: S.flip = 5; break;
605 case 180: S.flip = 3; break;
606 case 90: S.flip = 6; break;
609 write_fun = &LibRaw::write_ppm_tiff;
611 if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
613 S.height += S.height & 1;
614 S.width += S.width & 1;
617 IO.shrink = P1.filters && (O.half_size || O.threshold || O.aber[0] != 1 || O.aber[2] != 1);
618 S.iheight = (S.height + IO.shrink) >> IO.shrink;
619 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
621 SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
624 return LIBRAW_SUCCESS;
627 int LibRaw::unpack(void)
629 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
630 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
631 try {
633 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
634 if (O.shot_select >= P1.raw_count)
635 return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
637 if(!load_raw)
638 return LIBRAW_UNSPECIFIED_ERROR;
640 if (O.use_camera_matrix && C.cmatrix[0][0] > 0.25)
642 memcpy (C.rgb_cam, C.cmatrix, sizeof (C.cmatrix));
643 IO.raw_color = 0;
645 // already allocated ?
646 if(imgdata.image) free(imgdata.image);
648 imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
649 merror (imgdata.image, "unpack()");
652 if(S.top_margin || S.left_margin || S.right_margin || S.bottom_margin)
654 unsigned sz = S.raw_height*(S.left_margin+S.right_margin)
655 + S.width*(S.top_margin+S.bottom_margin);
656 imgdata.masked_pixels.buffer = (ushort*) calloc(sz, sizeof(ushort));
657 merror (imgdata.masked_pixels.buffer, "unpack()");
658 init_masked_ptrs();
660 if (libraw_internal_data.unpacker_data.meta_length)
662 libraw_internal_data.internal_data.meta_data =
663 (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
664 merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
666 ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
667 // foveon_load_raw produces different data for document_mode, we'll
668 // deal with it in dcraw_document_mode_processing
669 int save_document_mode = O.document_mode;
670 O.document_mode = 0;
672 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
673 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
675 (this->*load_raw)();
677 O.document_mode = save_document_mode;
679 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
680 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
682 SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
683 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
685 return 0;
687 catch ( LibRaw_exceptions err) {
688 EXCEPTION_HANDLER(err);
692 int LibRaw::dcraw_document_mode_processing(void)
694 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
695 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
697 try {
699 if(IO.fwidth)
700 rotate_fuji_raw();
702 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
703 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
705 O.document_mode = 2;
706 if(P1.is_foveon)
708 // filter image data for foveon document mode
709 short *iptr = (short *)imgdata.image;
710 for (int i=0; i < S.height*S.width*4; i++)
712 if ((short) iptr[i] < 0)
713 iptr[i] = 0;
715 SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
718 O.use_fuji_rotate = 0;
719 if (!(O.filtering_mode & LIBRAW_FILTERING_NOZEROES) && IO.zero_is_bad)
721 remove_zeroes();
722 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
724 if(O.bad_pixels)
726 bad_pixels(O.bad_pixels);
727 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
729 if (O.dark_frame)
731 subtract (O.dark_frame);
732 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
734 if(O.filtering_mode & LIBRAW_FILTERING_NOBLACKS)
735 C.black=0;
737 if (O.user_black >= 0)
738 C.black = O.user_black;
740 if (O.user_sat > 0)
741 C.maximum = O.user_sat;
743 pre_interpolate();
744 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
746 if (libraw_internal_data.internal_output_params.mix_green)
748 int i;
749 for (P1.colors=3, i=0; i < S.height*S.width; i++)
750 imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
752 SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
754 if (!P1.is_foveon && P1.colors == 3)
755 median_filter();
756 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
758 if (!P1.is_foveon && O.highlight == 2)
759 blend_highlights();
761 if (!P1.is_foveon && O.highlight > 2)
762 recover_highlights();
763 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
765 if (O.use_fuji_rotate)
766 fuji_rotate();
767 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
768 #ifndef NO_LCMS
769 if(O.camera_profile)
771 apply_profile(O.camera_profile,O.output_profile);
772 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
774 #endif
775 if(!libraw_internal_data.output_data.histogram)
777 libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
778 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_document_mode_processing()");
780 convert_to_rgb();
781 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
783 if (O.use_fuji_rotate)
784 stretch();
785 SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
787 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
788 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
790 return 0;
792 catch ( LibRaw_exceptions err) {
793 EXCEPTION_HANDLER(err);
798 #if 1
799 #define FORC(cnt) for (c=0; c < cnt; c++)
800 #define FORCC FORC(ret->colors)
801 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
803 libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
805 if(!T.thumb)
807 if ( !ID.toffset)
809 if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
811 else
813 if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
815 return NULL;
818 if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
820 libraw_processed_image_t * ret =
821 (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
823 if(!ret)
825 if(errcode) *errcode= ENOMEM;
826 return NULL;
829 bzero(ret,sizeof(libraw_processed_image_t));
830 ret->type = LIBRAW_IMAGE_BITMAP;
831 ret->height = T.theight;
832 ret->width = T.twidth;
833 ret->colors = 3;
834 ret->bits = 8;
835 ret->gamma_corrected = 1;
836 ret->data_size = T.tlength;
837 memmove(ret->data,T.thumb,T.tlength);
838 if(errcode) *errcode= 0;
839 return ret;
841 else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
843 ushort exif[5];
844 int mk_exif = 0;
845 if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
847 int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
849 libraw_processed_image_t * ret =
850 (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
852 if(!ret)
854 if(errcode) *errcode= ENOMEM;
855 return NULL;
858 bzero(ret,sizeof(libraw_processed_image_t));
860 ret->type = LIBRAW_IMAGE_JPEG;
861 ret->data_size = dsize;
863 ret->data[0] = 0xff;
864 ret->data[1] = 0xd8;
865 if(mk_exif)
867 struct tiff_hdr th;
868 memcpy (exif, "\xff\xe1 Exif\0\0", 10);
869 exif[1] = htons (8 + sizeof th);
870 memmove(ret->data+2,exif,sizeof(exif));
871 tiff_head (&th, 0);
872 memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
873 memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
875 else
877 memmove(ret->data+2,T.thumb+2,T.tlength-2);
879 if(errcode) *errcode= 0;
880 return ret;
883 else
885 if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
886 return NULL;
893 libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
895 if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE)
897 if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
898 return NULL;
901 if(!libraw_internal_data.output_data.histogram)
903 libraw_internal_data.output_data.histogram =
904 (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
905 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_make_mem_image()");
908 unsigned ds = S.height * S.width * (O.output_bps/8) * P1.colors;
909 libraw_processed_image_t *ret = (libraw_processed_image_t*)::malloc(sizeof(libraw_processed_image_t)+ds);
910 if(!ret)
912 if(errcode) *errcode= ENOMEM;
913 return NULL;
915 bzero(ret,sizeof(libraw_processed_image_t));
916 // metadata init
918 int s_iheight = S.iheight;
919 int s_iwidth = S.iwidth;
920 int s_width = S.width;
921 int s_hwight = S.height;
923 S.iheight = S.height;
924 S.iwidth = S.width;
927 if (S.flip & 4) SWAP(S.height,S.width);
930 ret->type = LIBRAW_IMAGE_BITMAP;
931 ret->height = S.height;
932 ret->width = S.width;
933 ret->colors = P1.colors;
934 ret->bits = O.output_bps;
935 ret->gamma_corrected = (O.output_bps == 8)?1:O.gamma_16bit;
937 ret->data_size = ds;
939 // Cut'n'paste from write_tiff_ppm, should be generalized later
940 uchar *bufp = ret->data;
941 uchar *ppm;
942 ushort *ppm2,lut16[0x10000];
943 int c, row, col, soff, rstep, cstep;
946 if (ret->bits == 8 || ret->gamma_corrected ) gamma_lut (lut16);
947 soff = flip_index (0, 0);
948 cstep = flip_index (0, 1) - soff;
949 rstep = flip_index (1, 0) - flip_index (0, S.width);
952 for (row=0; row < ret->height; row++, soff += rstep)
954 ppm2 = (ushort*) (ppm = bufp);
955 for (col=0; col < ret->width; col++, soff += cstep)
956 if (ret->bits == 8)
957 FORCC ppm [col*ret->colors+c] = lut16[imgdata.image[soff][c]]/256;
958 else if(ret->gamma_corrected)
959 FORCC ppm2[col*ret->colors+c] = lut16[imgdata.image[soff][c]];
960 else
961 FORCC ppm2[col*ret->colors+c] = imgdata.image[soff][c];
962 bufp+=ret->colors*(ret->bits/8)*ret->width;
964 if(errcode) *errcode= 0;
966 S.iheight = s_iheight;
967 S.iwidth = s_iwidth;
968 S.width = s_width;
969 S.height = s_hwight;
971 return ret;
974 #undef FORC
975 #undef FORCC
976 #undef SWAP
977 #endif
980 int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
982 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
984 if(!imgdata.image)
985 return LIBRAW_OUT_OF_ORDER_CALL;
987 if(!filename)
988 return ENOENT;
989 FILE *f = fopen(filename,"wb");
991 if(!f)
992 return errno;
994 try {
995 if(!libraw_internal_data.output_data.histogram)
997 libraw_internal_data.output_data.histogram =
998 (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
999 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
1001 write_ppm_tiff(f);
1002 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1003 fclose(f);
1004 return 0;
1006 catch ( LibRaw_exceptions err) {
1007 fclose(f);
1008 EXCEPTION_HANDLER(err);
1012 void LibRaw::kodak_thumb_loader()
1014 // some kodak cameras
1015 ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
1016 int s_colors = P1.colors;
1017 unsigned s_filters = P1.filters;
1018 ushort (*s_image)[4] = imgdata.image;
1021 S.height = T.theight;
1022 S.width = T.twidth;
1023 P1.filters = 0;
1025 if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw)
1027 S.height += S.height & 1;
1028 S.width += S.width & 1;
1031 imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
1032 merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
1034 ID.input->seek(ID.toffset, SEEK_SET);
1035 // read kodak thumbnail into T.image[]
1036 (this->*thumb_load_raw)();
1038 // copy-n-paste from image pipe
1039 #define MIN(a,b) ((a) < (b) ? (a) : (b))
1040 #define MAX(a,b) ((a) > (b) ? (a) : (b))
1041 #define LIM(x,min,max) MAX(min,MIN(x,max))
1042 #define CLIP(x) LIM(x,0,65535)
1043 #define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
1045 // from scale_colors
1047 double dmax;
1048 float scale_mul[4];
1049 int c,val;
1050 for (dmax=DBL_MAX, c=0; c < 3; c++)
1051 if (dmax > C.pre_mul[c])
1052 dmax = C.pre_mul[c];
1054 for( c=0; c< 3; c++)
1055 scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
1056 scale_mul[3] = scale_mul[1];
1058 size_t size = S.height * S.width;
1059 for (int i=0; i < size*4 ; i++)
1061 val = imgdata.image[0][i];
1062 if(!val) continue;
1063 val *= scale_mul[i & 3];
1064 imgdata.image[0][i] = CLIP(val);
1068 // from convert_to_rgb
1069 ushort *img;
1070 int row,col;
1072 int (*t_hist)[LIBRAW_HISTOGRAM_SIZE] = (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
1073 merror (t_hist, "LibRaw::kodak_thumb_loader()");
1075 float out[3],
1076 out_cam[3][4] =
1078 {2.81761312, -1.98369181, 0.166078627, 0},
1079 {-0.111855984, 1.73688626, -0.625030339, 0},
1080 {-0.0379119813, -0.891268849, 1.92918086, 0}
1083 for (img=imgdata.image[0], row=0; row < S.height; row++)
1084 for (col=0; col < S.width; col++, img+=4)
1086 out[0] = out[1] = out[2] = 0;
1087 for(int c=0;c<3;c++)
1089 out[0] += out_cam[0][c] * img[c];
1090 out[1] += out_cam[1][c] * img[c];
1091 out[2] += out_cam[2][c] * img[c];
1093 for(int c=0; c<3; c++)
1094 img[c] = CLIP((int) out[c]);
1095 for(int c=0; c<P1.colors;c++)
1096 t_hist[c][img[c] >> 3]++;
1100 // from gamma_lut
1101 int (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
1102 libraw_internal_data.output_data.histogram = t_hist;
1104 ushort *lut16 = (ushort*)calloc(0x10000,sizeof(ushort));
1105 merror(lut16,"LibRaw::kodak_thumb_loader()");
1106 gamma_lut(lut16);
1108 libraw_internal_data.output_data.histogram = save_hist;
1110 free(t_hist);
1112 // from write_ppm_tiff - copy pixels into bitmap
1114 S.iheight = S.height;
1115 S.iwidth = S.width;
1116 if (S.flip & 4) SWAP(S.height,S.width);
1118 if(T.thumb) free(T.thumb);
1119 T.thumb = (char*) calloc (S.width * S.height, P1.colors);
1120 merror (T.thumb, "LibRaw::kodak_thumb_loader()");
1121 T.tlength = S.width * S.height * P1.colors;
1123 // from write_tiff_ppm
1125 int soff = flip_index (0, 0);
1126 int cstep = flip_index (0, 1) - soff;
1127 int rstep = flip_index (1, 0) - flip_index (0, S.width);
1129 for (int row=0; row < S.height; row++, soff += rstep)
1131 char *ppm = T.thumb + row*S.width*P1.colors;
1132 for (int col=0; col < S.width; col++, soff += cstep)
1133 for(int c = 0; c < P1.colors; c++)
1134 ppm [col*P1.colors+c] = lut16[imgdata.image[soff][c]]/256;
1137 free(lut16);
1138 // restore variables
1139 free(imgdata.image);
1140 imgdata.image = s_image;
1142 T.twidth = S.width;
1143 S.width = s_width;
1145 S.iwidth = s_iwidth;
1146 S.iheight = s_iheight;
1148 T.theight = S.height;
1149 S.height = s_height;
1151 T.tcolors = P1.colors;
1152 P1.colors = s_colors;
1154 P1.filters = s_filters;
1156 #undef MIN
1157 #undef MAX
1158 #undef LIM
1159 #undef CLIP
1160 #undef SWAP
1163 void LibRaw::foveon_thumb_loader (void)
1165 unsigned bwide, row, col, bitbuf=0, bit=1, c, i;
1166 struct decode *dindex;
1167 short pred[3];
1169 if(T.thumb) free(T.thumb);
1170 T.thumb = NULL;
1172 bwide = get4();
1173 if (bwide > 0)
1175 if (bwide < T.twidth*3) return;
1176 T.thumb = (char*)malloc(3*T.twidth * T.theight);
1177 merror (T.thumb, "foveon_thumb()");
1178 char *buf = (char*)malloc(bwide);
1179 merror (buf, "foveon_thumb()");
1180 for (row=0; row < T.theight; row++)
1182 ID.input->read(buf, 1, bwide);
1183 memmove(T.thumb+(row*T.twidth*3),buf,T.twidth*3);
1185 free(buf);
1186 T.tlength = 3*T.twidth * T.theight;
1187 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1188 return;
1190 else
1192 foveon_decoder (256, 0);
1193 T.thumb = (char*)malloc(3*T.twidth * T.theight);
1194 char *bufp = T.thumb;
1195 merror (T.thumb, "foveon_thumb()");
1196 for (row=0; row < T.theight; row++)
1198 memset (pred, 0, sizeof pred);
1199 if (!bit) get4();
1200 for (bit=col=0; col < T.twidth; col++)
1201 for(c=0;c<3;c++)
1203 for (dindex=first_decode; dindex->branch[0]; )
1205 if ((bit = (bit-1) & 31) == 31)
1206 for (i=0; i < 4; i++)
1207 bitbuf = (bitbuf << 8) + ID.input->get_char();
1208 dindex = dindex->branch[bitbuf >> bit & 1];
1210 pred[c] += dindex->leaf;
1211 (*bufp++)=pred[c];
1214 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1215 T.tlength = 3*T.twidth * T.theight;
1217 return;
1221 // Äîñòàåò thumbnail èç ôàéëà, ñòàâèò thumb_format â ñîîòâåòñòâèè ñ ôîðìàòîì
1222 int LibRaw::unpack_thumb(void)
1224 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1225 CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
1227 try {
1228 if ( !ID.toffset)
1230 return LIBRAW_NO_THUMBNAIL;
1232 else if (thumb_load_raw)
1234 kodak_thumb_loader();
1235 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1236 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1237 return 0;
1239 else
1241 ID.input->seek(ID.toffset, SEEK_SET);
1242 if ( write_thumb == &LibRaw::jpeg_thumb)
1244 if(T.thumb) free(T.thumb);
1245 T.thumb = (char *) malloc (T.tlength);
1246 merror (T.thumb, "jpeg_thumb()");
1247 ID.input->read (T.thumb, 1, T.tlength);
1248 T.tcolors = 3;
1249 T.tformat = LIBRAW_THUMBNAIL_JPEG;
1250 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1251 return 0;
1253 else if (write_thumb == &LibRaw::ppm_thumb)
1255 T.tlength = T.twidth * T.theight*3;
1256 if(T.thumb) free(T.thumb);
1258 T.thumb = (char *) malloc (T.tlength);
1259 merror (T.thumb, "ppm_thumb()");
1261 ID.input->read(T.thumb, 1, T.tlength);
1263 T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1264 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1265 return 0;
1268 else if (write_thumb == &LibRaw::foveon_thumb)
1270 foveon_thumb_loader();
1271 // may return with error, so format is set in
1272 // foveon thumb loader itself
1273 SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1274 return 0;
1276 // else if -- all other write_thumb cases!
1277 else
1279 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1282 // last resort
1283 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1285 catch ( LibRaw_exceptions err) {
1286 EXCEPTION_HANDLER(err);
1291 int LibRaw::dcraw_thumb_writer(const char *fname)
1293 // CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);
1295 if(!fname)
1296 return ENOENT;
1298 FILE *tfp = fopen(fname,"wb");
1300 if(!tfp)
1301 return errno;
1303 if(!T.thumb)
1305 fclose(tfp);
1306 return LIBRAW_OUT_OF_ORDER_CALL;
1309 try {
1310 switch (T.tformat)
1312 case LIBRAW_THUMBNAIL_JPEG:
1313 jpeg_thumb_writer (tfp,T.thumb,T.tlength);
1314 break;
1315 case LIBRAW_THUMBNAIL_BITMAP:
1316 fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
1317 fwrite (T.thumb, 1, T.tlength, tfp);
1318 break;
1319 default:
1320 fclose(tfp);
1321 return LIBRAW_UNSUPPORTED_THUMBNAIL;
1323 fclose(tfp);
1324 return 0;
1326 catch ( LibRaw_exceptions err) {
1327 fclose(tfp);
1328 EXCEPTION_HANDLER(err);
1332 int LibRaw::adjust_sizes_info_only(void)
1334 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1335 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_FUJI_ROTATE);
1336 if (O.use_fuji_rotate)
1338 if (IO.fuji_width)
1340 // restore saved values
1341 if(IO.fheight)
1343 S.height = IO.fheight;
1344 S.width = IO.fwidth;
1345 S.iheight = (S.height + IO.shrink) >> IO.shrink;
1346 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
1347 S.raw_height -= 2*S.top_margin;
1348 IO.fheight = IO.fwidth = 0; // prevent repeated calls
1350 // dcraw code
1351 IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
1352 S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
1353 S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
1355 else
1357 if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
1358 if (S.pixel_aspect > 1) S.iwidth = (ushort) (S.iwidth * S.pixel_aspect + 0.5);
1361 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1362 if (S.flip & 4)
1364 unsigned short t = S.iheight;
1365 S.iheight=S.iwidth;
1366 S.iwidth = t;
1367 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1369 return 0;
1372 int LibRaw::rotate_fuji_raw(void)
1374 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1375 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1378 if(!IO.fwidth) return LIBRAW_SUCCESS;
1379 int row,col,r,c;
1380 ushort (*newimage)[4];
1381 ushort fiwidth,fiheight;
1383 fiheight = (IO.fheight + IO.shrink) >> IO.shrink;
1384 fiwidth = (IO.fwidth + IO.shrink) >> IO.shrink;
1386 newimage = (ushort (*)[4]) calloc (fiheight*fiwidth, sizeof (*newimage));
1387 merror(newimage,"rotate_fuji_raw()");
1388 for(row=0;row<S.height;row++)
1390 for(col=0;col<S.width;col++)
1393 if (libraw_internal_data.unpacker_data.fuji_layout) {
1394 r = IO.fuji_width - 1 - col + (row >> 1);
1395 c = col + ((row+1) >> 1);
1396 } else {
1397 r = IO.fuji_width - 1 + row - (col >> 1);
1398 c = row + ((col+1) >> 1);
1400 newimage[((r) >> IO.shrink)*fiwidth + ((c) >> IO.shrink)][FC(r,c)] =
1401 imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][FC(row,col)];
1404 // restore fuji sizes!
1405 S.height = IO.fheight;
1406 S.width = IO.fwidth;
1407 S.iheight = (S.height + IO.shrink) >> IO.shrink;
1408 S.iwidth = (S.width + IO.shrink) >> IO.shrink;
1409 S.raw_height -= 2*S.top_margin;
1410 IO.fheight = IO.fwidth = 0; // prevent repeated calls
1412 free(imgdata.image);
1413 imgdata.image = newimage;
1414 return LIBRAW_SUCCESS;
1419 int LibRaw::dcraw_process(void)
1421 int quality,i;
1424 CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1425 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1427 try {
1429 if(IO.fwidth)
1430 rotate_fuji_raw();
1433 if(!own_filtering_supported() && (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT))
1434 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC_BIT; // turn on black and zeroes filtering
1436 if(O.half_size)
1437 O.four_color_rgb = 1;
1439 if (!(O.filtering_mode & LIBRAW_FILTERING_NOZEROES) && IO.zero_is_bad)
1441 remove_zeroes();
1442 SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
1444 if(O.bad_pixels)
1446 bad_pixels(O.bad_pixels);
1447 SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
1449 if (O.dark_frame)
1451 subtract (O.dark_frame);
1452 SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
1455 quality = 2 + !IO.fuji_width;
1457 if(O.filtering_mode & LIBRAW_FILTERING_NOBLACKS)
1458 C.black=0;
1460 if (O.user_qual >= 0) quality = O.user_qual;
1461 if (O.user_black >= 0) C.black = O.user_black;
1462 if (O.user_sat > 0) C.maximum = O.user_sat;
1464 if (P1.is_foveon && !O.document_mode)
1466 foveon_interpolate();
1467 SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
1470 if (!P1.is_foveon && O.document_mode < 2)
1472 scale_colors();
1473 SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
1476 pre_interpolate();
1477 SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1479 if (P1.filters && !O.document_mode)
1481 if (quality == 0)
1482 lin_interpolate();
1483 else if (quality == 1 || P1.colors > 3)
1484 vng_interpolate();
1485 else if (quality == 2)
1486 ppg_interpolate();
1487 else
1488 ahd_interpolate();
1489 SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
1491 if (IO.mix_green)
1493 for (P1.colors=3, i=0; i < S.height * S.width; i++)
1494 imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
1495 SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
1498 if(!P1.is_foveon)
1500 if (P1.colors == 3)
1502 median_filter();
1503 SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
1506 if (O.highlight == 2)
1508 blend_highlights();
1509 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1512 if (O.highlight > 2)
1514 recover_highlights();
1515 SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1518 if (O.use_fuji_rotate)
1520 fuji_rotate();
1521 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1524 if(!libraw_internal_data.output_data.histogram)
1526 libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1527 merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
1529 #ifndef NO_LCMS
1530 if(O.camera_profile)
1532 apply_profile(O.camera_profile,O.output_profile);
1533 SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
1535 #endif
1537 convert_to_rgb();
1538 SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
1540 if (O.use_fuji_rotate)
1542 stretch();
1543 SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
1545 if (O.filtering_mode & LIBRAW_FILTERING_AUTOMATIC_BIT)
1546 O.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; // restore automated mode
1547 return 0;
1549 catch ( LibRaw_exceptions err) {
1550 EXCEPTION_HANDLER(err);
1554 // Supported cameras:
1555 static const char *static_camera_list[] =
1557 "Adobe Digital Negative (DNG)",
1558 "Apple QuickTake 100",
1559 "Apple QuickTake 150",
1560 "Apple QuickTake 200",
1561 "AVT F-080C",
1562 "AVT F-145C",
1563 "AVT F-201C",
1564 "AVT F-510C",
1565 "AVT F-810C",
1566 "Canon PowerShot 600",
1567 "Canon PowerShot A5",
1568 "Canon PowerShot A5 Zoom",
1569 "Canon PowerShot A50",
1570 "Canon PowerShot A460 (CHDK hack)",
1571 "Canon PowerShot A530 (CHDK hack)",
1572 "Canon PowerShot A610 (CHDK hack)",
1573 "Canon PowerShot A620 (CHDK hack)",
1574 "Canon PowerShot A630 (CHDK hack)",
1575 "Canon PowerShot A640 (CHDK hack)",
1576 "Canon PowerShot A650 (CHDK hack)",
1577 "Canon PowerShot A710 IS (CHDK hack)",
1578 "Canon PowerShot A720 IS (CHDK hack)",
1579 "Canon PowerShot Pro70",
1580 "Canon PowerShot Pro90 IS",
1581 "Canon PowerShot G1",
1582 "Canon PowerShot G2",
1583 "Canon PowerShot G3",
1584 "Canon PowerShot G5",
1585 "Canon PowerShot G6",
1586 "Canon PowerShot G7 (CHDK hack)",
1587 "Canon PowerShot G9",
1588 "Canon PowerShot G10",
1589 "Canon PowerShot S2 IS (CHDK hack)",
1590 "Canon PowerShot S3 IS (CHDK hack)",
1591 "Canon PowerShot S5 IS (CHDK hack)",
1592 "Canon PowerShot SD300 (CHDK hack)",
1593 "Canon PowerShot S30",
1594 "Canon PowerShot S40",
1595 "Canon PowerShot S45",
1596 "Canon PowerShot S50",
1597 "Canon PowerShot S60",
1598 "Canon PowerShot S70",
1599 "Canon PowerShot Pro1",
1600 "Canon EOS D30",
1601 "Canon EOS D60",
1602 "Canon EOS 5D",
1603 "Canon EOS 5D Mark II",
1604 "Canon EOS 10D",
1605 "Canon EOS 20D",
1606 "Canon EOS 30D",
1607 "Canon EOS 40D",
1608 "Canon EOS 50D",
1609 "Canon EOS 300D / Digital Rebel / Kiss Digital",
1610 "Canon EOS 350D / Digital Rebel XT / Kiss Digital N",
1611 "Canon EOS 400D / Digital Rebel XTi / Kiss Digital X",
1612 "Canon EOS 450D / Digital Rebel XSi / Kiss Digital X2",
1613 "Canon EOS 1000D / Digital Rebel XS / Kiss Digital F",
1614 "Canon EOS D2000C",
1615 "Canon EOS-1D",
1616 "Canon EOS-1DS",
1617 "Canon EOS-1D Mark II",
1618 "Canon EOS-1D Mark III",
1619 "Canon EOS-1D Mark II N",
1620 "Canon EOS-1Ds Mark II",
1621 "Canon EOS-1Ds Mark III",
1622 "Casio QV-2000UX",
1623 "Casio QV-3000EX",
1624 "Casio QV-3500EX",
1625 "Casio QV-4000",
1626 "Casio QV-5700",
1627 "Casio QV-R41",
1628 "Casio QV-R51",
1629 "Casio QV-R61",
1630 "Casio EX-S100",
1631 "Casio EX-Z4",
1632 "Casio EX-Z50",
1633 "Casio EX-Z55",
1634 "Casio Exlim Pro 505",
1635 "Casio Exlim Pro 600",
1636 "Casio Exlim Pro 700",
1637 "Contax N Digital",
1638 "Creative PC-CAM 600",
1639 "Epson R-D1",
1640 "Foculus 531C",
1641 "Fuji FinePix E550",
1642 "Fuji FinePix E900",
1643 "Fuji FinePix F700",
1644 "Fuji FinePix F710",
1645 "Fuji FinePix F800",
1646 "Fuji FinePix F810",
1647 "Fuji FinePix S2Pro",
1648 "Fuji FinePix S3Pro",
1649 "Fuji FinePix S5Pro",
1650 "Fuji FinePix S20Pro",
1651 "Fuji FinePix S100FS",
1652 "Fuji FinePix S5000",
1653 "Fuji FinePix S5100/S5500",
1654 "Fuji FinePix S5200/S5600",
1655 "Fuji FinePix S6000fd",
1656 "Fuji FinePix S7000",
1657 "Fuji FinePix S9000/S9500",
1658 "Fuji FinePix S9100/S9600",
1659 "Fuji IS-1",
1660 "Hasselblad CFV",
1661 "Hasselblad H3D",
1662 "Hasselblad V96C",
1663 "Imacon Ixpress 16-megapixel",
1664 "Imacon Ixpress 22-megapixel",
1665 "Imacon Ixpress 39-megapixel",
1666 "ISG 2020x1520",
1667 "Kodak DC20 (see Oliver Hartman's page)",
1668 "Kodak DC25 (see Jun-ichiro Itoh's page)",
1669 "Kodak DC40",
1670 "Kodak DC50",
1671 "Kodak DC120 (also try kdc2tiff)",
1672 "Kodak DCS200",
1673 "Kodak DCS315C",
1674 "Kodak DCS330C",
1675 "Kodak DCS420",
1676 "Kodak DCS460",
1677 "Kodak DCS460A",
1678 "Kodak DCS520C",
1679 "Kodak DCS560C",
1680 "Kodak DCS620C",
1681 "Kodak DCS620X",
1682 "Kodak DCS660C",
1683 "Kodak DCS660M",
1684 "Kodak DCS720X",
1685 "Kodak DCS760C",
1686 "Kodak DCS760M",
1687 "Kodak EOSDCS1",
1688 "Kodak EOSDCS3B",
1689 "Kodak NC2000F",
1690 "Kodak ProBack",
1691 "Kodak PB645C",
1692 "Kodak PB645H",
1693 "Kodak PB645M",
1694 "Kodak DCS Pro 14n",
1695 "Kodak DCS Pro 14nx",
1696 "Kodak DCS Pro SLR/c",
1697 "Kodak DCS Pro SLR/n",
1698 "Kodak C330",
1699 "Kodak C603",
1700 "Kodak P850",
1701 "Kodak P880",
1702 "Kodak KAI-0340",
1703 "Konica KD-400Z",
1704 "Konica KD-510Z",
1705 "Leaf AFi 7",
1706 "Leaf Aptus 17",
1707 "Leaf Aptus 22",
1708 "Leaf Aptus 54S",
1709 "Leaf Aptus 65",
1710 "Leaf Aptus 75",
1711 "Leaf Aptus 75S",
1712 "Leaf Cantare",
1713 "Leaf CatchLight",
1714 "Leaf CMost",
1715 "Leaf DCB2",
1716 "Leaf Valeo 6",
1717 "Leaf Valeo 11",
1718 "Leaf Valeo 17",
1719 "Leaf Valeo 22",
1720 "Leaf Volare",
1721 "Leica Digilux 2",
1722 "Leica Digilux 3",
1723 "Leica D-LUX2",
1724 "Leica D-LUX3",
1725 "Leica D-LUX4",
1726 "Leica V-LUX1",
1727 "Logitech Fotoman Pixtura",
1728 "Mamiya ZD",
1729 "Micron 2010",
1730 "Minolta RD175",
1731 "Minolta DiMAGE 5",
1732 "Minolta DiMAGE 7",
1733 "Minolta DiMAGE 7i",
1734 "Minolta DiMAGE 7Hi",
1735 "Minolta DiMAGE A1",
1736 "Minolta DiMAGE A2",
1737 "Minolta DiMAGE A200",
1738 "Minolta DiMAGE G400",
1739 "Minolta DiMAGE G500",
1740 "Minolta DiMAGE G530",
1741 "Minolta DiMAGE G600",
1742 "Minolta DiMAGE Z2",
1743 "Minolta Alpha/Dynax/Maxxum 5D",
1744 "Minolta Alpha/Dynax/Maxxum 7D",
1745 "Nikon D1",
1746 "Nikon D1H",
1747 "Nikon D1X",
1748 "Nikon D2H",
1749 "Nikon D2Hs",
1750 "Nikon D2X",
1751 "Nikon D2Xs",
1752 "Nikon D3",
1753 "Nikon D40",
1754 "Nikon D40X",
1755 "Nikon D50",
1756 "Nikon D60",
1757 "Nikon D70",
1758 "Nikon D70s",
1759 "Nikon D80",
1760 "Nikon D90",
1761 "Nikon D100",
1762 "Nikon D200",
1763 "Nikon D300",
1764 "Nikon D700",
1765 "Nikon E700 (\"DIAG RAW\" hack)",
1766 "Nikon E800 (\"DIAG RAW\" hack)",
1767 "Nikon E880 (\"DIAG RAW\" hack)",
1768 "Nikon E900 (\"DIAG RAW\" hack)",
1769 "Nikon E950 (\"DIAG RAW\" hack)",
1770 "Nikon E990 (\"DIAG RAW\" hack)",
1771 "Nikon E995 (\"DIAG RAW\" hack)",
1772 "Nikon E2100 (\"DIAG RAW\" hack)",
1773 "Nikon E2500 (\"DIAG RAW\" hack)",
1774 "Nikon E3200 (\"DIAG RAW\" hack)",
1775 "Nikon E3700 (\"DIAG RAW\" hack)",
1776 "Nikon E4300 (\"DIAG RAW\" hack)",
1777 "Nikon E4500 (\"DIAG RAW\" hack)",
1778 "Nikon E5000",
1779 "Nikon E5400",
1780 "Nikon E5700",
1781 "Nikon E8400",
1782 "Nikon E8700",
1783 "Nikon E8800",
1784 "Nikon Coolpix P6000",
1785 "Nikon Coolpix S6 (\"DIAG RAW\" hack)",
1786 "Nokia N95",
1787 "Olympus C3030Z",
1788 "Olympus C5050Z",
1789 "Olympus C5060WZ",
1790 "Olympus C7070WZ",
1791 "Olympus C70Z,C7000Z",
1792 "Olympus C740UZ",
1793 "Olympus C770UZ",
1794 "Olympus C8080WZ",
1795 "Olympus E-1",
1796 "Olympus E-3",
1797 "Olympus E-10",
1798 "Olympus E-20",
1799 "Olympus E-300",
1800 "Olympus E-330",
1801 "Olympus E-400",
1802 "Olympus E-410",
1803 "Olympus E-420",
1804 "Olympus E-500",
1805 "Olympus E-510",
1806 "Olympus E-520",
1807 "Olympus SP310",
1808 "Olympus SP320",
1809 "Olympus SP350",
1810 "Olympus SP500UZ",
1811 "Olympus SP510UZ",
1812 "Olympus SP550UZ",
1813 "Olympus SP560UZ",
1814 "Olympus SP570UZ",
1815 "Panasonic DMC-FZ8",
1816 "Panasonic DMC-FZ18",
1817 "Panasonic DMC-FZ28",
1818 "Panasonic DMC-FZ30",
1819 "Panasonic DMC-FZ50",
1820 "Panasonic DMC-FX150",
1821 "Panasonic DMC-G1",
1822 "Panasonic DMC-L1",
1823 "Panasonic DMC-L10",
1824 "Panasonic DMC-LC1",
1825 "Panasonic DMC-LX1",
1826 "Panasonic DMC-LX2",
1827 "Panasonic DMC-LX3",
1828 "Pentax *ist D",
1829 "Pentax *ist DL",
1830 "Pentax *ist DL2",
1831 "Pentax *ist DS",
1832 "Pentax *ist DS2",
1833 "Pentax K10D",
1834 "Pentax K20D",
1835 "Pentax K100D",
1836 "Pentax K100D Super",
1837 "Pentax K200D",
1838 "Pentax Optio S",
1839 "Pentax Optio S4",
1840 "Pentax Optio 33WR",
1841 "Pentax Optio 750Z",
1842 "Phase One LightPhase",
1843 "Phase One H 10",
1844 "Phase One H 20",
1845 "Phase One H 25",
1846 "Phase One P 20",
1847 "Phase One P 25",
1848 "Phase One P 30",
1849 "Phase One P 45",
1850 "Pixelink A782",
1851 "Polaroid x530",
1852 "Rollei d530flex",
1853 "RoverShot 3320af",
1854 "Samsung GX-1S",
1855 "Samsung GX-10",
1856 "Samsung S85 (hacked)",
1857 "Sarnoff 4096x5440",
1858 "Sigma SD9",
1859 "Sigma SD10",
1860 "Sigma SD14",
1861 "Sinar 3072x2048",
1862 "Sinar 4080x4080",
1863 "Sinar 4080x5440",
1864 "Sinar STI format",
1865 "SMaL Ultra-Pocket 3",
1866 "SMaL Ultra-Pocket 4",
1867 "SMaL Ultra-Pocket 5",
1868 "Sony DSC-F828",
1869 "Sony DSC-R1",
1870 "Sony DSC-V3",
1871 "Sony DSLR-A100",
1872 "Sony DSLR-A200",
1873 "Sony DSLR-A300",
1874 "Sony DSLR-A350",
1875 "Sony DSLR-A700",
1876 "Sony DSLR-A900",
1877 "Sony XCD-SX910CR",
1878 "STV680 VGA",
1879 NULL
1882 const char** LibRaw::cameraList() { return static_camera_list;}
1883 int LibRaw::cameraCount() { return (sizeof(static_camera_list)/sizeof(static_camera_list[0]))-1; }
1886 const char * LibRaw::strprogress(enum LibRaw_progress p)
1888 switch(p)
1890 case LIBRAW_PROGRESS_START:
1891 return "Starting";
1892 case LIBRAW_PROGRESS_OPEN :
1893 return "Opening file";
1894 case LIBRAW_PROGRESS_IDENTIFY :
1895 return "Reading metadata";
1896 case LIBRAW_PROGRESS_SIZE_ADJUST:
1897 return "Adjusting size";
1898 case LIBRAW_PROGRESS_LOAD_RAW:
1899 return "Reading RAW data";
1900 case LIBRAW_PROGRESS_REMOVE_ZEROES:
1901 return "Clearing zero values";
1902 case LIBRAW_PROGRESS_BAD_PIXELS :
1903 return "Removing dead pixels";
1904 case LIBRAW_PROGRESS_DARK_FRAME:
1905 return "Subtracting dark frame data";
1906 case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
1907 return "Interpolating Foveon sensor data";
1908 case LIBRAW_PROGRESS_SCALE_COLORS:
1909 return "Scaling colors";
1910 case LIBRAW_PROGRESS_PRE_INTERPOLATE:
1911 return "Pre-interpolating";
1912 case LIBRAW_PROGRESS_INTERPOLATE:
1913 return "Interpolating";
1914 case LIBRAW_PROGRESS_MIX_GREEN :
1915 return "Mixing green channels";
1916 case LIBRAW_PROGRESS_MEDIAN_FILTER :
1917 return "Median filter";
1918 case LIBRAW_PROGRESS_HIGHLIGHTS:
1919 return "Highlight recovery";
1920 case LIBRAW_PROGRESS_FUJI_ROTATE :
1921 return "Rotating Fuji diagonal data";
1922 case LIBRAW_PROGRESS_FLIP :
1923 return "Flipping image";
1924 case LIBRAW_PROGRESS_APPLY_PROFILE:
1925 return "ICC conversion";
1926 case LIBRAW_PROGRESS_CONVERT_RGB:
1927 return "Converting to RGB";
1928 case LIBRAW_PROGRESS_STRETCH:
1929 return "Stretching image";
1930 case LIBRAW_PROGRESS_THUMB_LOAD:
1931 return "Loading thumbnail";
1932 default:
1933 return "Some strange things";