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