3
* Copyright 2008-2009 LibRaw LLC (info@libraw.org)
4
* Created: Sat Mar 8 , 2008
6
* LibRaw (Lite) C++ interface (implementation)
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Lesser General Public
10
License as published by the Free Software Foundation; either
11
version 2.1 of the License, or (at your option) any later version.
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Lesser General Public License for more details.
18
You should have received a copy of the GNU Lesser General Public
19
License along with this library; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include <netinet/in.h>
31
#define LIBRAW_LIBRARY_BUILD
32
#include "libraw/libraw.h"
38
void default_memory_callback(void *,const char *file,const char *where)
40
fprintf (stderr,"%s: Out of memory in %s\n", file?file:"unknown file", where);
43
void default_data_callback(void*,const char *file, const int offset)
46
fprintf (stderr,"%s: Unexpected end of file\n", file?file:"unknown file");
48
fprintf (stderr,"%s: data corrupted at %d\n",file?file:"unknown file",offset);
50
const char *libraw_strerror(int e)
52
enum LibRaw_errors errorcode = (LibRaw_errors)e;
57
case LIBRAW_UNSPECIFIED_ERROR:
58
return "Unspecified error";
59
case LIBRAW_FILE_UNSUPPORTED:
60
return "Unsupported file format or not RAW file";
61
case LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE:
62
return "Request for nonexisting image number";
63
case LIBRAW_OUT_OF_ORDER_CALL:
64
return "Out of order call of libraw function";
65
case LIBRAW_NO_THUMBNAIL:
66
return "No thumbnail in file";
67
case LIBRAW_UNSUPPORTED_THUMBNAIL:
68
return "Unsupported thumbnail format";
69
case LIBRAW_CANNOT_ADDMASK:
70
return "Cannot add masked pixels to resized image";
71
case LIBRAW_UNSUFFICIENT_MEMORY:
72
return "Unsufficient memory";
73
case LIBRAW_DATA_ERROR:
74
return "Corrupted data or unexpected EOF";
76
return "Input/output error";
77
case LIBRAW_CANCELLED_BY_CALLBACK:
78
return "Cancelled by user callback";
80
return "Unknown error code";
89
const double LibRaw_constants::xyz_rgb[3][3] =
91
{ 0.412453, 0.357580, 0.180423 },
92
{ 0.212671, 0.715160, 0.072169 },
93
{ 0.019334, 0.119193, 0.950227 }
96
const float LibRaw_constants::d65_white[3] = { 0.950456, 1, 1.088754 };
98
#define P1 imgdata.idata
99
#define S imgdata.sizes
100
#define O imgdata.params
101
#define C imgdata.color
102
#define T imgdata.thumbnail
103
#define IO libraw_internal_data.internal_output_params
104
#define ID libraw_internal_data.internal_data
106
#define EXCEPTION_HANDLER(e) do{ \
107
fprintf(stderr,"Exception %d caught\n",e); \
110
case LIBRAW_EXCEPTION_ALLOC: \
112
return LIBRAW_UNSUFFICIENT_MEMORY; \
113
case LIBRAW_EXCEPTION_DECODE_RAW: \
114
case LIBRAW_EXCEPTION_DECODE_JPEG: \
116
return LIBRAW_DATA_ERROR; \
117
case LIBRAW_EXCEPTION_IO_EOF: \
118
case LIBRAW_EXCEPTION_IO_CORRUPT: \
120
return LIBRAW_IO_ERROR; \
121
case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK:\
123
return LIBRAW_CANCELLED_BY_CALLBACK; \
125
return LIBRAW_UNSPECIFIED_ERROR; \
129
void LibRaw::derror()
131
if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input)
133
if (libraw_internal_data.internal_data.input->eof())
135
if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
136
libraw_internal_data.internal_data.input->fname(),-1);
137
throw LIBRAW_EXCEPTION_IO_EOF;
141
if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
142
libraw_internal_data.internal_data.input->fname(),
143
libraw_internal_data.internal_data.input->tell());
144
throw LIBRAW_EXCEPTION_IO_CORRUPT;
147
libraw_internal_data.unpacker_data.data_error = 1;
149
LibRaw:: LibRaw(unsigned int flags)
151
double aber[4] = {1,1,1,1};
152
double gamm[5] = { 0.45,4.5,0,0,0 };
153
unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX };
159
bzero(&imgdata,sizeof(imgdata));
160
bzero(&libraw_internal_data,sizeof(libraw_internal_data));
161
bzero(&callbacks,sizeof(callbacks));
162
callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL: &default_memory_callback;
163
callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
164
memmove(&imgdata.params.aber,&aber,sizeof(aber));
165
memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
166
memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
168
imgdata.params.bright=1;
169
imgdata.params.use_camera_matrix=-1;
170
imgdata.params.user_flip=-1;
171
imgdata.params.user_black=-1;
172
imgdata.params.user_sat=-1;
173
imgdata.params.user_qual=-1;
174
imgdata.params.output_color=1;
175
imgdata.params.output_bps=8;
176
imgdata.params.use_fuji_rotate=1;
177
imgdata.params.auto_bright_thr = 0.01;
178
imgdata.parent_class = this;
179
imgdata.progress_flags = 0;
180
tls = new LibRaw_TLS;
185
void* LibRaw:: malloc(size_t t)
187
void *p = memmgr.malloc(t);
190
void* LibRaw:: calloc(size_t n,size_t t)
192
void *p = memmgr.calloc(n,t);
195
void LibRaw:: free(void *p)
201
int LibRaw:: fc (int row, int col)
203
static const char filter[16][16] =
204
{ { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
205
{ 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
206
{ 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
207
{ 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
208
{ 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
209
{ 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
210
{ 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
211
{ 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
212
{ 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
213
{ 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
214
{ 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
215
{ 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
216
{ 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
217
{ 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
218
{ 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
219
{ 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
221
if (imgdata.idata.filters != 1) return FC(row,col);
222
return filter[(row+imgdata.sizes.top_margin) & 15][(col+imgdata.sizes.left_margin) & 15];
225
void LibRaw:: recycle()
227
if(libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal)
229
delete libraw_internal_data.internal_data.input;
230
libraw_internal_data.internal_data.input = NULL;
232
libraw_internal_data.internal_data.input_internal = 0;
233
#define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
236
FREE(imgdata.thumbnail.thumb);
237
FREE(libraw_internal_data.internal_data.meta_data);
238
FREE(libraw_internal_data.output_data.histogram);
239
FREE(libraw_internal_data.output_data.oprof);
240
FREE(imgdata.color.profile);
242
#define ZERO(a) bzero(&a,sizeof(a))
244
ZERO(libraw_internal_data.internal_output_params);
247
imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
248
imgdata.progress_flags = 0;
253
const char * LibRaw::unpack_function_name()
255
if(!load_raw) return "Function not set";
257
// sorted names order
258
if (load_raw == &LibRaw::adobe_dng_load_raw_lj) return "adobe_dng_load_raw_lj()";
259
if (load_raw == &LibRaw::adobe_dng_load_raw_nc) return "adobe_dng_load_raw_nc()";
260
if (load_raw == &LibRaw::canon_600_load_raw) return "canon_600_load_raw()";
262
if (load_raw == &LibRaw::canon_a5_load_raw) return "canon_a5_load_raw()";
263
if (load_raw == &LibRaw::canon_compressed_load_raw) return "canon_compressed_load_raw()";
264
if (load_raw == &LibRaw::canon_sraw_load_raw) return "canon_sraw_load_raw()";
266
if (load_raw == &LibRaw::casio_qv5700_load_raw ) return "casio_qv5700_load_raw()";
267
if (load_raw == &LibRaw::eight_bit_load_raw ) return "eight_bit_load_raw()";
268
if (load_raw == &LibRaw::fuji_load_raw ) return "fuji_load_raw()";
270
if (load_raw == &LibRaw::hasselblad_load_raw ) return "hasselblad_load_raw()";
271
if (load_raw == &LibRaw::imacon_full_load_raw ) return "imacon_full_load_raw()";
272
if (load_raw == &LibRaw::kodak_262_load_raw ) return "kodak_262_load_raw()";
274
if (load_raw == &LibRaw::kodak_65000_load_raw ) return "kodak_65000_load_raw()";
275
if (load_raw == &LibRaw::kodak_dc120_load_raw ) return "kodak_dc120_load_raw()";
276
if (load_raw == &LibRaw::kodak_jpeg_load_raw ) return "kodak_jpeg_load_raw()";
278
if (load_raw == &LibRaw::kodak_radc_load_raw ) return "kodak_radc_load_raw()";
279
if (load_raw == &LibRaw::kodak_rgb_load_raw ) return "kodak_rgb_load_raw()";
280
if (load_raw == &LibRaw::kodak_yrgb_load_raw ) return "kodak_yrgb_load_raw()";
281
if (load_raw == &LibRaw::kodak_ycbcr_load_raw ) return "kodak_ycbcr_load_raw()";
283
if (load_raw == &LibRaw::leaf_hdr_load_raw ) return "leaf_hdr_load_raw()";
284
if (load_raw == &LibRaw::lossless_jpeg_load_raw) return "lossless_jpeg_load_raw()";
285
if (load_raw == &LibRaw::minolta_rd175_load_raw ) return "minolta_rd175_load_raw()";
287
if (load_raw == &LibRaw::nikon_compressed_load_raw) return "nikon_compressed_load_raw()";
288
if (load_raw == &LibRaw::nikon_e900_load_raw ) return "nikon_e900_load_raw()";
289
if (load_raw == &LibRaw::nokia_load_raw ) return "nokia_load_raw()";
291
if (load_raw == &LibRaw::olympus_e300_load_raw ) return "olympus_e300_load_raw()";
292
if (load_raw == &LibRaw::olympus_e410_load_raw ) return "olympus_e410_load_raw()";
293
if (load_raw == &LibRaw::packed_12_load_raw ) return "packed_12_load_raw()";
294
if (load_raw == &LibRaw::panasonic_load_raw ) return "panasonic_load_raw()";
296
if (load_raw == &LibRaw::pentax_k10_load_raw ) return "pentax_k10_load_raw()";
297
if (load_raw == &LibRaw::phase_one_load_raw ) return "phase_one_load_raw()";
298
if (load_raw == &LibRaw::phase_one_load_raw_c ) return "phase_one_load_raw_c()";
300
if (load_raw == &LibRaw::quicktake_100_load_raw ) return "quicktake_100_load_raw()";
301
if (load_raw == &LibRaw::rollei_load_raw ) return "rollei_load_raw()";
302
if (load_raw == &LibRaw::sinar_4shot_load_raw ) return "sinar_4shot_load_raw()";
304
if (load_raw == &LibRaw::smal_v6_load_raw ) return "smal_v6_load_raw()";
305
if (load_raw == &LibRaw::smal_v9_load_raw ) return "smal_v9_load_raw()";
306
if (load_raw == &LibRaw::sony_load_raw ) return "sony_load_raw()";
307
if (load_raw == &LibRaw::sony_arw_load_raw ) return "sony_arw_load_raw()";
309
if (load_raw == &LibRaw::sony_arw2_load_raw ) return "sony_arw2_load_raw()";
310
if (load_raw == &LibRaw::unpacked_load_raw ) return "unpacked_load_raw()";
313
return "Unknown unpack function";
317
void LibRaw:: merror (void *ptr, const char *where)
320
if(callbacks.mem_cb)(*callbacks.mem_cb)(callbacks.memcb_data,
321
libraw_internal_data.internal_data.input
322
?libraw_internal_data.internal_data.input->fname()
325
throw LIBRAW_EXCEPTION_ALLOC;
329
int LibRaw::open_file(const char *fname)
331
// this stream will close on recycle()
332
LibRaw_file_datastream *stream = new LibRaw_file_datastream(fname);
336
return LIBRAW_IO_ERROR;
338
ID.input_internal = 0; // preserve from deletion on error
339
int ret = open_datastream(stream);
340
if (ret == LIBRAW_SUCCESS)
342
ID.input_internal =1 ; // flag to delete datastream on recycle
347
ID.input_internal = 0;
352
int LibRaw::open_buffer(void *buffer, size_t size)
354
// this stream will close on recycle()
355
if(!buffer || buffer==(void*)-1)
356
return LIBRAW_IO_ERROR;
358
LibRaw_buffer_datastream *stream = new LibRaw_buffer_datastream(buffer,size);
362
return LIBRAW_IO_ERROR;
364
ID.input_internal = 0; // preserve from deletion on error
365
int ret = open_datastream(stream);
366
if (ret == LIBRAW_SUCCESS)
368
ID.input_internal =1 ; // flag to delete datastream on recycle
373
ID.input_internal = 0;
379
int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
385
return LIBRAW_IO_ERROR;
390
SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
392
if (O.use_camera_matrix < 0)
393
O.use_camera_matrix = O.use_camera_wb;
397
int saved_raw_width = S.raw_width;
398
int saved_width = S.width;
399
// from packed_12_load_raw
400
if ((load_raw == &LibRaw:: packed_12_load_raw) && (S.raw_width * 2 >= S.width * 3))
402
// raw_width is in bytes!
403
S.raw_width = S.raw_width * 2 / 3;
405
else if (S.pixel_aspect < 0.95 || S.pixel_aspect > 1.05)
407
S.width*=S.pixel_aspect;
410
if(S.raw_width>S.width + S.left_margin)
411
S.right_margin = S.raw_width - S.width - S.left_margin;
413
if(S.raw_height > S.height + S.top_margin)
414
S.bottom_margin = S.raw_height - S.height - S.top_margin;
416
S.raw_width = saved_raw_width;
417
S.width = saved_width;
421
if(C.profile) free(C.profile);
422
C.profile = malloc(C.profile_length);
423
merror(C.profile,"LibRaw::open_file()");
424
ID.input->seek(ID.profile_offset,SEEK_SET);
425
ID.input->read(C.profile,C.profile_length,1);
428
SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
430
catch ( LibRaw_exceptions err) {
431
EXCEPTION_HANDLER(err);
435
return LIBRAW_FILE_UNSUPPORTED;
437
if (O.user_flip >= 0)
438
S.flip = O.user_flip;
440
switch ((S.flip+3600) % 360)
442
case 270: S.flip = 5; break;
443
case 180: S.flip = 3; break;
444
case 90: S.flip = 6; break;
447
write_fun = &LibRaw::write_ppm_tiff;
449
if (load_raw == &LibRaw::kodak_ycbcr_load_raw)
451
S.height += S.height & 1;
452
S.width += S.width & 1;
455
IO.shrink = P1.filters && (O.half_size || O.threshold || O.aber[0] != 1 || O.aber[2] != 1);
456
S.iheight = (S.height + IO.shrink) >> IO.shrink;
457
S.iwidth = (S.width + IO.shrink) >> IO.shrink;
459
SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
462
return LIBRAW_SUCCESS;
465
int LibRaw::unpack(void)
467
CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
468
CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
471
RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
472
if (O.shot_select >= P1.raw_count)
473
return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
476
return LIBRAW_UNSPECIFIED_ERROR;
478
if (O.use_camera_matrix && C.cmatrix[0][0] > 0.25)
480
memcpy (C.rgb_cam, C.cmatrix, sizeof (C.cmatrix));
483
// already allocated ?
484
if(imgdata.image) free(imgdata.image);
486
imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
487
merror (imgdata.image, "unpack()");
489
if (libraw_internal_data.unpacker_data.meta_length)
491
libraw_internal_data.internal_data.meta_data =
492
(char *) malloc (libraw_internal_data.unpacker_data.meta_length);
493
merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
495
ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
496
// foveon_load_raw produces different data for document_mode, we'll
497
// deal with it in dcraw_document_mode_processing
498
int save_document_mode = O.document_mode;
503
O.document_mode = save_document_mode;
505
SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
506
RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
510
catch ( LibRaw_exceptions err) {
511
EXCEPTION_HANDLER(err);
515
int LibRaw::dcraw_document_mode_processing(void)
517
CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
518
CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
524
O.use_fuji_rotate = 0;
528
SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
532
bad_pixels(O.bad_pixels);
533
SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
537
subtract (O.dark_frame);
538
SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
541
if (O.user_black >= 0)
542
C.black = O.user_black;
545
C.maximum = O.user_sat;
548
SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
550
if (libraw_internal_data.internal_output_params.mix_green)
553
for (P1.colors=3, i=0; i < S.height*S.width; i++)
554
imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
556
SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
560
SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
562
if ( O.highlight == 2)
565
if ( O.highlight > 2)
566
recover_highlights();
567
SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
569
if (O.use_fuji_rotate)
571
SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
575
apply_profile(O.camera_profile,O.output_profile);
576
SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
579
if(!libraw_internal_data.output_data.histogram)
581
libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
582
merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_document_mode_processing()");
585
SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
587
if (O.use_fuji_rotate)
589
SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
593
catch ( LibRaw_exceptions err) {
594
EXCEPTION_HANDLER(err);
600
#define FORC(cnt) for (c=0; c < cnt; c++)
601
#define FORCC FORC(ret->colors)
602
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
604
libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
610
if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
614
if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
619
if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
621
libraw_processed_image_t * ret =
622
(libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
626
if(errcode) *errcode= ENOMEM;
630
bzero(ret,sizeof(libraw_processed_image_t));
631
ret->type = LIBRAW_IMAGE_BITMAP;
632
ret->height = T.theight;
633
ret->width = T.twidth;
636
ret->gamma_corrected = 1;
637
ret->data_size = T.tlength;
638
memmove(ret->data,T.thumb,T.tlength);
639
if(errcode) *errcode= 0;
642
else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
646
if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
648
int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
650
libraw_processed_image_t * ret =
651
(libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
655
if(errcode) *errcode= ENOMEM;
659
bzero(ret,sizeof(libraw_processed_image_t));
661
ret->type = LIBRAW_IMAGE_JPEG;
662
ret->data_size = dsize;
669
memcpy (exif, "\xff\xe1 Exif\0\0", 10);
670
exif[1] = htons (8 + sizeof th);
671
memmove(ret->data+2,exif,sizeof(exif));
673
memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
674
memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
678
memmove(ret->data+2,T.thumb+2,T.tlength-2);
680
if(errcode) *errcode= 0;
686
if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
694
libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
696
if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE)
698
if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
702
if(!libraw_internal_data.output_data.histogram)
704
libraw_internal_data.output_data.histogram =
705
(int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
706
merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_make_mem_image()");
709
unsigned ds = S.height * S.width * (O.output_bps/8) * P1.colors;
710
libraw_processed_image_t *ret = (libraw_processed_image_t*)::malloc(sizeof(libraw_processed_image_t)+ds);
713
if(errcode) *errcode= ENOMEM;
716
bzero(ret,sizeof(libraw_processed_image_t));
719
int s_iheight = S.iheight;
720
int s_iwidth = S.iwidth;
721
int s_width = S.width;
722
int s_hwight = S.height;
724
S.iheight = S.height;
728
if (S.flip & 4) SWAP(S.height,S.width);
731
ret->type = LIBRAW_IMAGE_BITMAP;
732
ret->height = S.height;
733
ret->width = S.width;
734
ret->colors = P1.colors;
735
ret->bits = O.output_bps;
736
ret->gamma_corrected = (O.output_bps == 8)?1:O.gamma_16bit;
740
// Cut'n'paste from write_tiff_ppm, should be generalized later
741
uchar *bufp = ret->data;
743
ushort *ppm2,lut16[0x10000];
744
int c, row, col, soff, rstep, cstep;
747
if (ret->bits == 8 || ret->gamma_corrected ) gamma_lut (lut16);
748
soff = flip_index (0, 0);
749
cstep = flip_index (0, 1) - soff;
750
rstep = flip_index (1, 0) - flip_index (0, S.width);
753
for (row=0; row < ret->height; row++, soff += rstep)
755
ppm2 = (ushort*) (ppm = bufp);
756
for (col=0; col < ret->width; col++, soff += cstep)
758
FORCC ppm [col*ret->colors+c] = lut16[imgdata.image[soff][c]]/256;
759
else if(ret->gamma_corrected)
760
FORCC ppm2[col*ret->colors+c] = lut16[imgdata.image[soff][c]];
762
FORCC ppm2[col*ret->colors+c] = imgdata.image[soff][c];
763
bufp+=ret->colors*(ret->bits/8)*ret->width;
765
if(errcode) *errcode= 0;
767
S.iheight = s_iheight;
781
int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
783
CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
786
return LIBRAW_OUT_OF_ORDER_CALL;
790
FILE *f = fopen(filename,"wb");
796
if(!libraw_internal_data.output_data.histogram)
798
libraw_internal_data.output_data.histogram =
799
(int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
800
merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
803
SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
807
catch ( LibRaw_exceptions err) {
809
EXCEPTION_HANDLER(err);
813
void LibRaw::kodak_thumb_loader()
815
// some kodak cameras
816
ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
817
int s_colors = P1.colors;
818
unsigned s_filters = P1.filters;
819
ushort (*s_image)[4] = imgdata.image;
822
S.height = T.theight;
826
if (thumb_load_raw == &CLASS kodak_ycbcr_load_raw)
828
S.height += S.height & 1;
829
S.width += S.width & 1;
832
imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
833
merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
835
ID.input->seek(ID.toffset, SEEK_SET);
836
// read kodak thumbnail into T.image[]
837
(this->*thumb_load_raw)();
839
// copy-n-paste from image pipe
840
#define MIN(a,b) ((a) < (b) ? (a) : (b))
841
#define MAX(a,b) ((a) > (b) ? (a) : (b))
842
#define LIM(x,min,max) MAX(min,MIN(x,max))
843
#define CLIP(x) LIM(x,0,65535)
844
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
851
for (dmax=DBL_MAX, c=0; c < 3; c++)
852
if (dmax > C.pre_mul[c])
856
scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
857
scale_mul[3] = scale_mul[1];
859
size_t size = S.height * S.width;
860
for (unsigned i=0; i < size*4 ; i++)
862
val = imgdata.image[0][i];
864
val *= scale_mul[i & 3];
865
imgdata.image[0][i] = CLIP(val);
869
// from convert_to_rgb
873
int (*t_hist)[LIBRAW_HISTOGRAM_SIZE] = (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
874
merror (t_hist, "LibRaw::kodak_thumb_loader()");
879
{2.81761312, -1.98369181, 0.166078627, 0},
880
{-0.111855984, 1.73688626, -0.625030339, 0},
881
{-0.0379119813, -0.891268849, 1.92918086, 0}
884
for (img=imgdata.image[0], row=0; row < S.height; row++)
885
for (col=0; col < S.width; col++, img+=4)
887
out[0] = out[1] = out[2] = 0;
890
out[0] += out_cam[0][c] * img[c];
891
out[1] += out_cam[1][c] * img[c];
892
out[2] += out_cam[2][c] * img[c];
894
for(int c=0; c<3; c++)
895
img[c] = CLIP((int) out[c]);
896
for(int c=0; c<P1.colors;c++)
897
t_hist[c][img[c] >> 3]++;
902
int (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
903
libraw_internal_data.output_data.histogram = t_hist;
905
ushort *lut16 = (ushort*)calloc(0x10000,sizeof(ushort));
906
merror(lut16,"LibRaw::kodak_thumb_loader()");
909
libraw_internal_data.output_data.histogram = save_hist;
913
// from write_ppm_tiff - copy pixels into bitmap
915
S.iheight = S.height;
917
if (S.flip & 4) SWAP(S.height,S.width);
919
if(T.thumb) free(T.thumb);
920
T.thumb = (char*) calloc (S.width * S.height, P1.colors);
921
merror (T.thumb, "LibRaw::kodak_thumb_loader()");
922
T.tlength = S.width * S.height * P1.colors;
924
// from write_tiff_ppm
926
int soff = flip_index (0, 0);
927
int cstep = flip_index (0, 1) - soff;
928
int rstep = flip_index (1, 0) - flip_index (0, S.width);
930
for (int row=0; row < S.height; row++, soff += rstep)
932
char *ppm = T.thumb + row*S.width*P1.colors;
933
for (int col=0; col < S.width; col++, soff += cstep)
934
for(int c = 0; c < P1.colors; c++)
935
ppm [col*P1.colors+c] = lut16[imgdata.image[soff][c]]/256;
941
imgdata.image = s_image;
947
S.iheight = s_iheight;
949
T.theight = S.height;
952
T.tcolors = P1.colors;
953
P1.colors = s_colors;
955
P1.filters = s_filters;
966
// ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ thumbnail ļæ½ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½, ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ thumb_format ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ ļæ½ ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½ļæ½
967
int LibRaw::unpack_thumb(void)
969
CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
970
CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
975
return LIBRAW_NO_THUMBNAIL;
977
else if (thumb_load_raw)
979
kodak_thumb_loader();
980
T.tformat = LIBRAW_THUMBNAIL_BITMAP;
981
SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
986
ID.input->seek(ID.toffset, SEEK_SET);
987
if ( write_thumb == &LibRaw::jpeg_thumb)
989
if(T.thumb) free(T.thumb);
990
T.thumb = (char *) malloc (T.tlength);
991
merror (T.thumb, "jpeg_thumb()");
992
ID.input->read (T.thumb, 1, T.tlength);
994
T.tformat = LIBRAW_THUMBNAIL_JPEG;
995
SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
998
else if (write_thumb == &LibRaw::ppm_thumb)
1000
T.tlength = T.twidth * T.theight*3;
1001
if(T.thumb) free(T.thumb);
1003
T.thumb = (char *) malloc (T.tlength);
1004
merror (T.thumb, "ppm_thumb()");
1006
ID.input->read(T.thumb, 1, T.tlength);
1008
T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1009
SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1013
// else if -- all other write_thumb cases!
1016
return LIBRAW_UNSUPPORTED_THUMBNAIL;
1020
return LIBRAW_UNSUPPORTED_THUMBNAIL;
1022
catch ( LibRaw_exceptions err) {
1023
EXCEPTION_HANDLER(err);
1028
int LibRaw::dcraw_thumb_writer(const char *fname)
1030
// CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);
1035
FILE *tfp = fopen(fname,"wb");
1043
return LIBRAW_OUT_OF_ORDER_CALL;
1049
case LIBRAW_THUMBNAIL_JPEG:
1050
jpeg_thumb_writer (tfp,T.thumb,T.tlength);
1052
case LIBRAW_THUMBNAIL_BITMAP:
1053
fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
1054
fwrite (T.thumb, 1, T.tlength, tfp);
1058
return LIBRAW_UNSUPPORTED_THUMBNAIL;
1063
catch ( LibRaw_exceptions err) {
1065
EXCEPTION_HANDLER(err);
1069
int LibRaw::adjust_sizes_info_only(void)
1071
CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1072
CHECK_ORDER_HIGH(LIBRAW_PROGRESS_FUJI_ROTATE);
1073
if (O.use_fuji_rotate)
1078
// restore saved values
1081
S.height = IO.fheight;
1082
S.width = IO.fwidth;
1083
S.iheight = (S.height + IO.shrink) >> IO.shrink;
1084
S.iwidth = (S.width + IO.shrink) >> IO.shrink;
1085
S.raw_height -= 2*S.top_margin;
1086
IO.fheight = IO.fwidth = 0; // prevent repeated calls
1090
IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
1091
S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
1092
S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
1096
if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
1097
if (S.pixel_aspect > 1) S.iwidth = (ushort) (S.iwidth * S.pixel_aspect + 0.5);
1100
SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1103
unsigned short t = S.iheight;
1106
SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1113
int LibRaw::dcraw_process(void)
1118
CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1119
CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1124
O.four_color_rgb = 1;
1129
SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
1133
bad_pixels(O.bad_pixels);
1134
SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
1138
subtract (O.dark_frame);
1139
SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
1142
quality = 2 + !IO.fuji_width;
1144
if (O.user_qual >= 0) quality = O.user_qual;
1145
if (O.user_black >= 0) C.black = O.user_black;
1146
if (O.user_sat > 0) C.maximum = O.user_sat;
1148
if ( O.document_mode < 2)
1151
SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
1155
SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1157
if (P1.filters && !O.document_mode)
1161
else if (quality == 1 || P1.colors > 3)
1163
else if (quality == 2)
1167
SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
1171
for (P1.colors=3, i=0; i < S.height * S.width; i++)
1172
imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
1173
SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
1181
SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
1184
if (O.highlight == 2)
1187
SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1190
if (O.highlight > 2)
1192
recover_highlights();
1193
SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1196
if (O.use_fuji_rotate)
1199
SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1202
if(!libraw_internal_data.output_data.histogram)
1204
libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1205
merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
1208
if(O.camera_profile)
1210
apply_profile(O.camera_profile,O.output_profile);
1211
SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
1216
SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
1218
if (O.use_fuji_rotate)
1221
SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
1225
catch ( LibRaw_exceptions err) {
1226
EXCEPTION_HANDLER(err);
1230
// Supported cameras:
1231
static const char *static_camera_list[] =
1233
"Adobe Digital Negative (DNG)",
1234
"Apple QuickTake 100",
1235
"Apple QuickTake 150",
1236
"Apple QuickTake 200",
1242
"Canon PowerShot 600",
1243
"Canon PowerShot A5",
1244
"Canon PowerShot A5 Zoom",
1245
"Canon PowerShot A50",
1246
"Canon PowerShot A460 (CHDK hack)",
1247
"Canon PowerShot A530 (CHDK hack)",
1248
"Canon PowerShot A610 (CHDK hack)",
1249
"Canon PowerShot A620 (CHDK hack)",
1250
"Canon PowerShot A630 (CHDK hack)",
1251
"Canon PowerShot A640 (CHDK hack)",
1252
"Canon PowerShot A650 (CHDK hack)",
1253
"Canon PowerShot A710 IS (CHDK hack)",
1254
"Canon PowerShot A720 IS (CHDK hack)",
1255
"Canon PowerShot Pro70",
1256
"Canon PowerShot Pro90 IS",
1257
"Canon PowerShot G1",
1258
"Canon PowerShot G2",
1259
"Canon PowerShot G3",
1260
"Canon PowerShot G5",
1261
"Canon PowerShot G6",
1262
"Canon PowerShot G7 (CHDK hack)",
1263
"Canon PowerShot G9",
1264
"Canon PowerShot G10",
1265
"Canon PowerShot S2 IS (CHDK hack)",
1266
"Canon PowerShot S3 IS (CHDK hack)",
1267
"Canon PowerShot S5 IS (CHDK hack)",
1268
"Canon PowerShot SD300 (CHDK hack)",
1269
"Canon PowerShot S30",
1270
"Canon PowerShot S40",
1271
"Canon PowerShot S45",
1272
"Canon PowerShot S50",
1273
"Canon PowerShot S60",
1274
"Canon PowerShot S70",
1275
"Canon PowerShot Pro1",
1279
"Canon EOS 5D Mark II",
1285
"Canon EOS 300D / Digital Rebel / Kiss Digital",
1286
"Canon EOS 350D / Digital Rebel XT / Kiss Digital N",
1287
"Canon EOS 400D / Digital Rebel XTi / Kiss Digital X",
1288
"Canon EOS 450D / Digital Rebel XSi / Kiss Digital X2",
1289
"Canon EOS 1000D / Digital Rebel XS / Kiss Digital F",
1293
"Canon EOS-1D Mark II",
1294
"Canon EOS-1D Mark III",
1295
"Canon EOS-1D Mark II N",
1296
"Canon EOS-1Ds Mark II",
1297
"Canon EOS-1Ds Mark III",
1310
"Casio Exlim Pro 505",
1311
"Casio Exlim Pro 600",
1312
"Casio Exlim Pro 700",
1314
"Creative PC-CAM 600",
1317
"Fuji FinePix E550",
1318
"Fuji FinePix E900",
1319
"Fuji FinePix F700",
1320
"Fuji FinePix F710",
1321
"Fuji FinePix F800",
1322
"Fuji FinePix F810",
1323
"Fuji FinePix S2Pro",
1324
"Fuji FinePix S3Pro",
1325
"Fuji FinePix S5Pro",
1326
"Fuji FinePix S20Pro",
1327
"Fuji FinePix S100FS",
1328
"Fuji FinePix S5000",
1329
"Fuji FinePix S5100/S5500",
1330
"Fuji FinePix S5200/S5600",
1331
"Fuji FinePix S6000fd",
1332
"Fuji FinePix S7000",
1333
"Fuji FinePix S9000/S9500",
1334
"Fuji FinePix S9100/S9600",
1339
"Imacon Ixpress 16-megapixel",
1340
"Imacon Ixpress 22-megapixel",
1341
"Imacon Ixpress 39-megapixel",
1343
"Kodak DC20 (see Oliver Hartman's page)",
1344
"Kodak DC25 (see Jun-ichiro Itoh's page)",
1347
"Kodak DC120 (also try kdc2tiff)",
1370
"Kodak DCS Pro 14n",
1371
"Kodak DCS Pro 14nx",
1372
"Kodak DCS Pro SLR/c",
1373
"Kodak DCS Pro SLR/n",
1403
"Logitech Fotoman Pixtura",
1409
"Minolta DiMAGE 7i",
1410
"Minolta DiMAGE 7Hi",
1411
"Minolta DiMAGE A1",
1412
"Minolta DiMAGE A2",
1413
"Minolta DiMAGE A200",
1414
"Minolta DiMAGE G400",
1415
"Minolta DiMAGE G500",
1416
"Minolta DiMAGE G530",
1417
"Minolta DiMAGE G600",
1418
"Minolta DiMAGE Z2",
1419
"Minolta Alpha/Dynax/Maxxum 5D",
1420
"Minolta Alpha/Dynax/Maxxum 7D",
1442
"Nikon E700 (\"DIAG RAW\" hack)",
1443
"Nikon E800 (\"DIAG RAW\" hack)",
1444
"Nikon E880 (\"DIAG RAW\" hack)",
1445
"Nikon E900 (\"DIAG RAW\" hack)",
1446
"Nikon E950 (\"DIAG RAW\" hack)",
1447
"Nikon E990 (\"DIAG RAW\" hack)",
1448
"Nikon E995 (\"DIAG RAW\" hack)",
1449
"Nikon E2100 (\"DIAG RAW\" hack)",
1450
"Nikon E2500 (\"DIAG RAW\" hack)",
1451
"Nikon E3200 (\"DIAG RAW\" hack)",
1452
"Nikon E3700 (\"DIAG RAW\" hack)",
1453
"Nikon E4300 (\"DIAG RAW\" hack)",
1454
"Nikon E4500 (\"DIAG RAW\" hack)",
1461
"Nikon Coolpix P6000",
1462
"Nikon Coolpix S6 (\"DIAG RAW\" hack)",
1468
"Olympus C70Z,C7000Z",
1492
"Panasonic DMC-FZ8",
1493
"Panasonic DMC-FZ18",
1494
"Panasonic DMC-FZ28",
1495
"Panasonic DMC-FZ30",
1496
"Panasonic DMC-FZ50",
1497
"Panasonic DMC-FX150",
1500
"Panasonic DMC-L10",
1501
"Panasonic DMC-LC1",
1502
"Panasonic DMC-LX1",
1503
"Panasonic DMC-LX2",
1504
"Panasonic DMC-LX3",
1513
"Pentax K100D Super",
1518
"Pentax Optio 33WR",
1519
"Pentax Optio 750Z",
1520
"Phase One LightPhase",
1533
"Samsung S85 (hacked)",
1534
"Sarnoff 4096x5440",
1539
"SMaL Ultra-Pocket 3",
1540
"SMaL Ultra-Pocket 4",
1541
"SMaL Ultra-Pocket 5",
1556
const char** LibRaw::cameraList() { return static_camera_list;}
1557
int LibRaw::cameraCount() { return (sizeof(static_camera_list)/sizeof(static_camera_list[0]))-1; }
1560
const char * LibRaw::strprogress(enum LibRaw_progress p)
1564
case LIBRAW_PROGRESS_START:
1566
case LIBRAW_PROGRESS_OPEN :
1567
return "Opening file";
1568
case LIBRAW_PROGRESS_IDENTIFY :
1569
return "Reading metadata";
1570
case LIBRAW_PROGRESS_SIZE_ADJUST:
1571
return "Adjusting size";
1572
case LIBRAW_PROGRESS_LOAD_RAW:
1573
return "Reading RAW data";
1574
case LIBRAW_PROGRESS_REMOVE_ZEROES:
1575
return "Clearing zero values";
1576
case LIBRAW_PROGRESS_BAD_PIXELS :
1577
return "Removing dead pixels";
1578
case LIBRAW_PROGRESS_DARK_FRAME:
1579
return "Subtracting dark frame data";
1580
case LIBRAW_PROGRESS_SCALE_COLORS:
1581
return "Scaling colors";
1582
case LIBRAW_PROGRESS_PRE_INTERPOLATE:
1583
return "Pre-interpolating";
1584
case LIBRAW_PROGRESS_INTERPOLATE:
1585
return "Interpolating";
1586
case LIBRAW_PROGRESS_MIX_GREEN :
1587
return "Mixing green channels";
1588
case LIBRAW_PROGRESS_MEDIAN_FILTER :
1589
return "Median filter";
1590
case LIBRAW_PROGRESS_HIGHLIGHTS:
1591
return "Highlight recovery";
1592
case LIBRAW_PROGRESS_FUJI_ROTATE :
1593
return "Rotating Fuji diagonal data";
1594
case LIBRAW_PROGRESS_FLIP :
1595
return "Flipping image";
1596
case LIBRAW_PROGRESS_APPLY_PROFILE:
1597
return "ICC conversion";
1598
case LIBRAW_PROGRESS_CONVERT_RGB:
1599
return "Converting to RGB";
1600
case LIBRAW_PROGRESS_STRETCH:
1601
return "Stretching image";
1602
case LIBRAW_PROGRESS_THUMB_LOAD:
1603
return "Loading thumbnail";
1605
return "Some strange things";