]> Creatis software - clitk.git/blob - utilities/CxImage/ximaraw.cpp
cosmetic
[clitk.git] / utilities / CxImage / ximaraw.cpp
1 /*
2  * File:        ximaraw.cpp
3  * Purpose:     Platform Independent RAW Image Class Loader
4  * 16/Dec/2007 Davide Pizzolato - www.xdp.it
5  * CxImage version 6.0.0 02/Feb/2008
6  * 
7  * CxImageRAW (c) May/2006 pdw63
8  *
9  * based on dcraw.c -- Dave Coffin's raw photo decoder
10  * Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
11  */
12
13 #include "ximaraw.h"
14
15 #if CXIMAGE_SUPPORT_RAW
16
17 ////////////////////////////////////////////////////////////////////////////////
18 #if CXIMAGE_SUPPORT_DECODE
19 ////////////////////////////////////////////////////////////////////////////////
20 bool CxImageRAW::Decode(CxFile *hFile)
21 {
22         if (hFile==NULL)
23                 return false;
24
25         DCRAW  dcr;
26
27   cx_try
28   {
29         // initialization
30         dcr_init_dcraw(&dcr);
31
32         dcr.opt.user_qual = GetCodecOption(CXIMAGE_FORMAT_RAW) & 0x03;
33
34         // setup variables for debugging
35         char szClass[] = "CxImageRAW";
36         dcr.ifname = szClass;
37         dcr.sz_error = info.szLastError;
38
39         // setup library options, see dcr_print_manual for the available switches
40         // call dcr_parse_command_line_options(&dcr,0,0,0) to set default options
41         // if (dcr_parse_command_line_options(&dcr,argc,argv,&arg))
42         if (dcr_parse_command_line_options(&dcr,0,0,0)){
43                 cx_throw("CxImageRAW: unknown option");
44         }
45
46         // set return point for error handling
47         if (setjmp (dcr.failure)) {
48                 cx_throw("");
49         }
50
51         // install file manager
52         CxFileRaw src(hFile,&dcr);
53
54         // check file header
55         dcr_identify(&dcr);
56         
57         if(!dcr.is_raw){
58                 cx_throw("CxImageRAW: not a raw image");
59         }
60
61         if (dcr.load_raw == NULL) {
62                 cx_throw("CxImageRAW: missing raw decoder");
63         }
64
65         // verify special case
66         if (dcr.load_raw == dcr_kodak_ycbcr_load_raw) {
67                 dcr.height += dcr.height & 1;
68                 dcr.width  += dcr.width  & 1;
69         }
70
71         if (info.nEscape == -1){
72                 head.biWidth = dcr.width;
73                 head.biHeight= dcr.height;
74                 info.dwType = CXIMAGE_FORMAT_RAW;
75                 cx_throw("output dimensions returned");
76         }
77
78         // shrinked decoding available and requested?
79         dcr.shrink = dcr.filters && (dcr.opt.half_size || dcr.opt.threshold || dcr.opt.aber[0] != 1 || dcr.opt.aber[2] != 1);
80         dcr.iheight = (dcr.height + dcr.shrink) >> dcr.shrink;
81         dcr.iwidth  = (dcr.width  + dcr.shrink) >> dcr.shrink;
82
83         // install custom camera matrix
84         if (dcr.opt.use_camera_matrix && dcr.cmatrix[0][0] > 0.25) {
85                 memcpy (dcr.rgb_cam, dcr.cmatrix, sizeof dcr.cmatrix);
86                 dcr.raw_color = 0;
87         }
88
89         // allocate memory for the image
90         dcr.image = (ushort (*)[4]) calloc (dcr.iheight*dcr.iwidth, sizeof *dcr.image);
91         dcr_merror (&dcr, dcr.image, szClass);
92
93         if (dcr.meta_length) {
94                 dcr.meta_data = (char *) malloc (dcr.meta_length);
95                 dcr_merror (&dcr, dcr.meta_data, szClass);
96         }
97
98         // start image decoder
99         hFile->Seek(dcr.data_offset, SEEK_SET);
100         (*dcr.load_raw)(&dcr);
101
102         // post processing
103         if (dcr.zero_is_bad) dcr_remove_zeroes(&dcr);
104
105         dcr_bad_pixels(&dcr);
106
107         if (dcr.opt.dark_frame) dcr_subtract (&dcr,dcr.opt.dark_frame);
108
109         dcr.quality = 2 + !dcr.fuji_width;
110
111         if (dcr.opt.user_qual >= 0) dcr.quality = dcr.opt.user_qual;
112
113         if (dcr.opt.user_black >= 0) dcr.black = dcr.opt.user_black;
114
115 #ifdef COLORCHECK
116         dcr_colorcheck(&dcr);
117 #endif
118
119 #if RESTRICTED
120         if (dcr.is_foveon && !dcr.opt.document_mode) dcr_foveon_interpolate(&dcr);
121 #endif
122
123         if (!dcr.is_foveon && dcr.opt.document_mode < 2) dcr_scale_colors(&dcr);
124
125         // pixel interpolation and filters
126         dcr_pre_interpolate(&dcr);
127
128         if (dcr.filters && !dcr.opt.document_mode) {
129                 if (dcr.quality == 0)
130                         dcr_lin_interpolate(&dcr);
131                 else if (dcr.quality == 1 || dcr.colors > 3)
132                         dcr_vng_interpolate(&dcr);
133                 else if (dcr.quality == 2)
134                         dcr_ppg_interpolate(&dcr);
135                 else
136                         dcr_ahd_interpolate(&dcr);
137         }
138
139         if (dcr.mix_green) {
140                 long i;
141                 for (dcr.colors=3, i=0; i < dcr.height*dcr.width; i++) {
142                         dcr.image[i][1] = (dcr.image[i][1] + dcr.image[i][3]) >> 1;
143                 }
144         }
145
146         if (!dcr.is_foveon && dcr.colors == 3) dcr_median_filter(&dcr);
147
148         if (!dcr.is_foveon && dcr.opt.highlight == 2) dcr_blend_highlights(&dcr);
149
150         if (!dcr.is_foveon && dcr.opt.highlight > 2) dcr_recover_highlights(&dcr);
151
152         if (dcr.opt.use_fuji_rotate) dcr_fuji_rotate(&dcr);
153
154 #ifndef NO_LCMS
155         if (dcr.opt.cam_profile) dcr_apply_profile (dcr.opt.cam_profile, dcr.opt.out_profile);
156 #endif
157
158         // final conversion
159         dcr_convert_to_rgb(&dcr);
160
161         if (dcr.opt.use_fuji_rotate) dcr_stretch(&dcr);
162
163         dcr.iheight = dcr.height;
164         dcr.iwidth  = dcr.width;
165         if (dcr.flip & 4) SWAP(dcr.height,dcr.width);
166
167         // ready to transfer data from dcr.image
168         if (!Create(dcr.width,dcr.height,24,CXIMAGE_FORMAT_RAW)){
169                 cx_throw("");
170         }
171
172         uchar  *ppm = (uchar *) calloc (dcr.width, dcr.colors*dcr.opt.output_bps/8);
173         ushort *ppm2 = (ushort *) ppm;
174         dcr_merror (&dcr, ppm, szClass);
175
176         uchar lut[0x10000];
177         if (dcr.opt.output_bps == 8) dcr_gamma_lut (&dcr, lut);
178
179         long c, row, col, soff, rstep, cstep;
180         soff  = dcr_flip_index (&dcr, 0, 0);
181         cstep = dcr_flip_index (&dcr, 0, 1) - soff;
182         rstep = dcr_flip_index (&dcr, 1, 0) - dcr_flip_index (&dcr, 0, dcr.width);
183         for (row=0; row < dcr.height; row++, soff += rstep) {
184                 for (col=0; col < dcr.width; col++, soff += cstep) {
185                         if (dcr.opt.output_bps == 8)
186                                 for (c=0; c < dcr.colors; c++) ppm [col*dcr.colors+c] = lut[dcr.image[soff][c]];
187                         else
188                                 for (c=0; c < dcr.colors; c++) ppm2[col*dcr.colors+c] = dcr.image[soff][c];
189                 }
190                 if (dcr.opt.output_bps == 16 && !dcr.opt.output_tiff && htons(0x55aa) != 0x55aa)
191                         _swab ((char*)ppm2, (char*)ppm2, dcr.width*dcr.colors*2);
192
193                 DWORD size = dcr.width * (dcr.colors*dcr.opt.output_bps/8);
194                 RGBtoBGR(ppm,size);
195                 memcpy(GetBits(dcr.height - 1 - row), ppm, min(size,GetEffWidth()));
196         }
197         free (ppm);
198
199
200         dcr_cleanup_dcraw(&dcr);
201
202   } cx_catch {
203
204         dcr_cleanup_dcraw(&dcr);
205
206         if (strcmp(message,"")) strncpy(info.szLastError,message,255);
207         if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_RAW) return true;
208         return false;
209   }
210         /* that's it */
211         return true;
212 }
213 ////////////////////////////////////////////////////////////////////////////////
214 #endif //CXIMAGE_SUPPORT_DECODE
215 ////////////////////////////////////////////////////////////////////////////////
216 #if CXIMAGE_SUPPORT_ENCODE
217 ////////////////////////////////////////////////////////////////////////////////
218 bool CxImageRAW::Encode(CxFile * hFile)
219 {
220         if (hFile == NULL) return false;
221         strcpy(info.szLastError, "Save RAW not supported");
222         return false;
223 }
224 ////////////////////////////////////////////////////////////////////////////////
225 #endif // CXIMAGE_SUPPORT_ENCODE
226 ////////////////////////////////////////////////////////////////////////////////
227 #endif // CXIMAGE_SUPPORT_RAW
228