/[projet1]/public/pc/shared_libraries/freeimage/v3.12.0/Source/FreeImage/J2KHelper.cpp
Defence Force logotype

Contents of /public/pc/shared_libraries/freeimage/v3.12.0/Source/FreeImage/J2KHelper.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 126 - (show annotations)
Mon Jul 13 12:20:10 2009 UTC (10 years, 7 months ago) by dbug
File size: 14119 byte(s)
Added some shared libraries (UnitTest++, and FreeImage) to avoid having every single project brings its own libraries.
Ideally people should add them in a way we can upgrade versions without breaking things:
-> public/pc/shared_libraries/library_name/library_version/actuall_content
1 // ==========================================================
2 // JPEG2000 helpers
3 //
4 // Design and implementation by
5 // - Hervé Drolon (drolon@infonie.fr)
6 //
7 // This file is part of FreeImage 3
8 //
9 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
17 // THIS DISCLAIMER.
18 //
19 // Use at your own risk!
20 // ==========================================================
21
22 #include "FreeImage.h"
23 #include "Utilities.h"
24 #include "../LibOpenJPEG/openjpeg.h"
25
26 /**
27 Divide an integer by a power of 2 and round upwards
28 @return Returns a divided by 2^b
29 */
30 static int int_ceildivpow2(int a, int b) {
31 return (a + (1 << b) - 1) >> b;
32 }
33
34 /**
35 Convert a OpenJPEG image to a FIBITMAP
36 @param format_id Plugin ID
37 @param image OpenJPEG image
38 @return Returns the converted image if successful, returns NULL otherwise
39 */
40 FIBITMAP* J2KImageToFIBITMAP(int format_id, const opj_image_t *image) {
41 FIBITMAP *dib = NULL;
42
43 try {
44 // compute image width and height
45
46 //int w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx);
47 int wr = image->comps[0].w;
48 int wrr = int_ceildivpow2(image->comps[0].w, image->comps[0].factor);
49
50 //int h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy);
51 //int hr = image->comps[0].h;
52 int hrr = int_ceildivpow2(image->comps[0].h, image->comps[0].factor);
53
54 // check the number of components
55
56 int numcomps = image->numcomps;
57
58 BOOL bIsValid = TRUE;
59 for(int c = 0; c < numcomps - 1; c++) {
60 if( (image->comps[c].dx == image->comps[c+1].dx) &&
61 (image->comps[c].dy == image->comps[c+1].dy) &&
62 (image->comps[c].prec == image->comps[c+1].prec) ) {
63 continue;
64 } else {
65 bIsValid = FALSE;
66 break;
67 }
68 }
69 bIsValid &= ((numcomps == 1) || (numcomps == 3) || (numcomps == 4));
70 if(!bIsValid) {
71 if(numcomps) {
72 FreeImage_OutputMessageProc(format_id, "Warning: image contains %d greyscale components. Only the first will be loaded.\n", numcomps);
73 numcomps = 1;
74 } else {
75 // unknown type
76 throw "Unsupported format";
77 }
78 }
79
80 // create a new DIB
81
82 if(image->comps[0].prec <= 8) {
83 switch(numcomps) {
84 case 1:
85 dib = FreeImage_Allocate(wrr, hrr, 8);
86 break;
87 case 3:
88 dib = FreeImage_Allocate(wrr, hrr, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
89 break;
90 case 4:
91 dib = FreeImage_Allocate(wrr, hrr, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
92 break;
93 }
94 } else if(image->comps[0].prec <= 16) {
95 switch(numcomps) {
96 case 1:
97 dib = FreeImage_AllocateT(FIT_UINT16, wrr, hrr);
98 break;
99 case 3:
100 dib = FreeImage_AllocateT(FIT_RGB16, wrr, hrr);
101 break;
102 case 4:
103 dib = FreeImage_AllocateT(FIT_RGBA16, wrr, hrr);
104 break;
105 }
106 } else {
107 throw "Unsupported format";
108 }
109 if(!dib) {
110 throw "DIB allocation failed";
111 }
112
113 if(image->comps[0].prec <= 8) {
114 if(numcomps == 1) {
115 // 8-bit greyscale
116 // ----------------------------------------------------------
117
118 // build a greyscale palette
119
120 RGBQUAD *pal = FreeImage_GetPalette(dib);
121 for (int i = 0; i < 256; i++) {
122 pal[i].rgbRed = (BYTE)i;
123 pal[i].rgbGreen = (BYTE)i;
124 pal[i].rgbBlue = (BYTE)i;
125 }
126
127 // load pixel data
128
129 unsigned pixel_count = 0;
130
131 for(int y = 0; y < hrr; y++) {
132 BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
133
134 for(int x = 0; x < wrr; x++) {
135 const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
136
137 int index = image->comps[0].data[pixel_pos];
138 index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
139
140 bits[x] = (BYTE)index;
141
142 pixel_count++;
143 }
144 }
145 }
146 else if(numcomps == 3) {
147
148 // 24-bit RGB
149 // ----------------------------------------------------------
150
151 // load pixel data
152
153 unsigned pixel_count = 0;
154
155 for(int y = 0; y < hrr; y++) {
156 BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
157
158 for(int x = 0; x < wrr; x++) {
159 const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
160
161 int r = image->comps[0].data[pixel_pos];
162 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
163
164 int g = image->comps[1].data[pixel_pos];
165 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
166
167 int b = image->comps[2].data[pixel_pos];
168 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
169
170 bits[FI_RGBA_RED] = (BYTE)r;
171 bits[FI_RGBA_GREEN] = (BYTE)g;
172 bits[FI_RGBA_BLUE] = (BYTE)b;
173 bits += 3;
174
175 pixel_count++;
176 }
177 }
178 }
179 else if(numcomps == 4) {
180
181 // 32-bit RGBA
182 // ----------------------------------------------------------
183
184 // load pixel data
185
186 unsigned pixel_count = 0;
187
188 for(int y = 0; y < hrr; y++) {
189 BYTE *bits = FreeImage_GetScanLine(dib, hrr - 1 - y);
190
191 for(int x = 0; x < wrr; x++) {
192 const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
193
194 int r = image->comps[0].data[pixel_pos];
195 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
196
197 int g = image->comps[1].data[pixel_pos];
198 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
199
200 int b = image->comps[2].data[pixel_pos];
201 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
202
203 int a = image->comps[3].data[pixel_pos];
204 a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
205
206 bits[FI_RGBA_RED] = (BYTE)r;
207 bits[FI_RGBA_GREEN] = (BYTE)g;
208 bits[FI_RGBA_BLUE] = (BYTE)b;
209 bits[FI_RGBA_ALPHA] = (BYTE)a;
210 bits += 4;
211
212 pixel_count++;
213 }
214 }
215 }
216 }
217 else if(image->comps[0].prec <= 16) {
218 if(numcomps == 1) {
219 // 16-bit greyscale
220 // ----------------------------------------------------------
221
222 // load pixel data
223
224 unsigned pixel_count = 0;
225
226 for(int y = 0; y < hrr; y++) {
227 unsigned short *bits = (unsigned short*)FreeImage_GetScanLine(dib, hrr - 1 - y);
228
229 for(int x = 0; x < wrr; x++) {
230 const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
231
232 int index = image->comps[0].data[pixel_pos];
233 index += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
234
235 bits[x] = (unsigned short)index;
236
237 pixel_count++;
238 }
239 }
240 }
241 else if(numcomps == 3) {
242
243 // 48-bit RGB
244 // ----------------------------------------------------------
245
246 // load pixel data
247
248 unsigned pixel_count = 0;
249
250 for(int y = 0; y < hrr; y++) {
251 FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
252
253 for(int x = 0; x < wrr; x++) {
254 const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
255
256 int r = image->comps[0].data[pixel_pos];
257 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
258
259 int g = image->comps[1].data[pixel_pos];
260 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
261
262 int b = image->comps[2].data[pixel_pos];
263 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
264
265 bits[x].red = (WORD)r;
266 bits[x].green = (WORD)g;
267 bits[x].blue = (WORD)b;
268
269 pixel_count++;
270 }
271 }
272 }
273 else if(numcomps == 4) {
274
275 // 64-bit RGBA
276 // ----------------------------------------------------------
277
278 // load pixel data
279
280 unsigned pixel_count = 0;
281
282 for(int y = 0; y < hrr; y++) {
283 FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, hrr - 1 - y);
284
285 for(int x = 0; x < wrr; x++) {
286 const unsigned pixel_pos = pixel_count / wrr * wr + pixel_count % wrr;
287
288 int r = image->comps[0].data[pixel_pos];
289 r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
290
291 int g = image->comps[1].data[pixel_pos];
292 g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
293
294 int b = image->comps[2].data[pixel_pos];
295 b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
296
297 int a = image->comps[3].data[pixel_pos];
298 a += (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
299
300 bits[x].red = (WORD)r;
301 bits[x].green = (WORD)g;
302 bits[x].blue = (WORD)b;
303 bits[x].alpha = (WORD)a;
304
305 pixel_count++;
306 }
307 }
308 }
309 }
310
311 return dib;
312
313 } catch(const char *text) {
314 if(dib) FreeImage_Unload(dib);
315 FreeImage_OutputMessageProc(format_id, text);
316 return NULL;
317 }
318
319 }
320
321 /**
322 Convert a FIBITMAP to a OpenJPEG image
323 @param format_id Plugin ID
324 @param dib FreeImage image
325 @param parameters Compression parameters
326 @return Returns the converted image if successful, returns NULL otherwise
327 */
328 opj_image_t* FIBITMAPToJ2KImage(int format_id, FIBITMAP *dib, const opj_cparameters_t *parameters) {
329 int prec, numcomps, x, y, index;
330 OPJ_COLOR_SPACE color_space;
331 opj_image_cmptparm_t cmptparm[4]; // maximum of 4 components
332 opj_image_t *image = NULL; // image to encode
333
334 try {
335 int w = FreeImage_GetWidth(dib);
336 int h = FreeImage_GetHeight(dib);
337
338 // get image characteristics
339 FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
340
341 if(image_type == FIT_BITMAP) {
342 // standard image ...
343 prec = 8;
344 switch(FreeImage_GetColorType(dib)) {
345 case FIC_MINISBLACK:
346 numcomps = 1;
347 color_space = CLRSPC_GRAY;
348 break;
349 case FIC_RGB:
350 numcomps = 3;
351 color_space = CLRSPC_SRGB;
352 break;
353 case FIC_RGBALPHA:
354 numcomps = 4;
355 color_space = CLRSPC_SRGB;
356 break;
357 default:
358 return NULL;
359 }
360 } else {
361 // HDR image ...
362 prec = 16;
363 switch(image_type) {
364 case FIT_UINT16:
365 numcomps = 1;
366 color_space = CLRSPC_GRAY;
367 break;
368 case FIT_RGB16:
369 numcomps = 3;
370 color_space = CLRSPC_SRGB;
371 break;
372 case FIT_RGBA16:
373 numcomps = 4;
374 color_space = CLRSPC_SRGB;
375 break;
376 default:
377 return NULL;
378 }
379 }
380
381 // initialize image components
382 memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
383 for(int i = 0; i < numcomps; i++) {
384 cmptparm[i].dx = parameters->subsampling_dx;
385 cmptparm[i].dy = parameters->subsampling_dy;
386 cmptparm[i].w = w;
387 cmptparm[i].h = h;
388 cmptparm[i].prec = prec;
389 cmptparm[i].bpp = prec;
390 cmptparm[i].sgnd = 0;
391 }
392 // create the image
393 image = opj_image_create(numcomps, &cmptparm[0], color_space);
394 if(!image) {
395 throw "DIB allocation failed";
396 }
397
398 // set image offset and reference grid
399 image->x0 = parameters->image_offset_x0;
400 image->y0 = parameters->image_offset_y0;
401 image->x1 = parameters->image_offset_x0 + (w - 1) * parameters->subsampling_dx + 1;
402 image->y1 = parameters->image_offset_y0 + (h - 1) * parameters->subsampling_dy + 1;
403
404 // set image data
405 if(prec == 8) {
406 switch(numcomps) {
407 case 1:
408 index = 0;
409 for(y = 0; y < h; y++) {
410 BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
411 for(x = 0; x < w; x++) {
412 image->comps[0].data[index] = bits[x];
413 index++;
414 }
415 }
416 break;
417 case 3:
418 index = 0;
419 for(y = 0; y < h; y++) {
420 BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
421 for(x = 0; x < w; x++) {
422 image->comps[0].data[index] = bits[FI_RGBA_RED];
423 image->comps[1].data[index] = bits[FI_RGBA_GREEN];
424 image->comps[2].data[index] = bits[FI_RGBA_BLUE];
425 bits += 3;
426 index++;
427 }
428 }
429 break;
430 case 4:
431 index = 0;
432 for(y = 0; y < h; y++) {
433 BYTE *bits = FreeImage_GetScanLine(dib, h - 1 - y);
434 for(x = 0; x < w; x++) {
435 image->comps[0].data[index] = bits[FI_RGBA_RED];
436 image->comps[1].data[index] = bits[FI_RGBA_GREEN];
437 image->comps[2].data[index] = bits[FI_RGBA_BLUE];
438 image->comps[3].data[index] = bits[FI_RGBA_ALPHA];
439 bits += 4;
440 index++;
441 }
442 }
443 break;
444 }
445 }
446 else if(prec == 16) {
447 switch(numcomps) {
448 case 1:
449 index = 0;
450 for(y = 0; y < h; y++) {
451 WORD *bits = (WORD*)FreeImage_GetScanLine(dib, h - 1 - y);
452 for(x = 0; x < w; x++) {
453 image->comps[0].data[index] = bits[x];
454 index++;
455 }
456 }
457 break;
458 case 3:
459 index = 0;
460 for(y = 0; y < h; y++) {
461 FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, h - 1 - y);
462 for(x = 0; x < w; x++) {
463 image->comps[0].data[index] = bits[x].red;
464 image->comps[1].data[index] = bits[x].green;
465 image->comps[2].data[index] = bits[x].blue;
466 index++;
467 }
468 }
469 break;
470 case 4:
471 index = 0;
472 for(y = 0; y < h; y++) {
473 FIRGBA16 *bits = (FIRGBA16*)FreeImage_GetScanLine(dib, h - 1 - y);
474 for(x = 0; x < w; x++) {
475 image->comps[0].data[index] = bits[x].red;
476 image->comps[1].data[index] = bits[x].green;
477 image->comps[2].data[index] = bits[x].blue;
478 image->comps[3].data[index] = bits[x].alpha;
479 index++;
480 }
481 }
482 break;
483 }
484 }
485
486 return image;
487
488 } catch (const char *text) {
489 if(image) opj_image_destroy(image);
490 FreeImage_OutputMessageProc(format_id, text);
491 return NULL;
492 }
493 }

  ViewVC Help
Powered by ViewVC 1.1.26