19949213aSStephan Aßmus /* 29949213aSStephan Aßmus 39949213aSStephan Aßmus Copyright (c) 2003, Marcin 'Shard' Konicki 49949213aSStephan Aßmus All rights reserved. 59949213aSStephan Aßmus 69949213aSStephan Aßmus Redistribution and use in source and binary forms, with or without 79949213aSStephan Aßmus modification, are permitted provided that the following conditions are met: 89949213aSStephan Aßmus 99949213aSStephan Aßmus * Redistributions of source code must retain the above copyright notice, 109949213aSStephan Aßmus this list of conditions and the following disclaimer. 119949213aSStephan Aßmus * Redistributions in binary form must reproduce the above copyright notice, 129949213aSStephan Aßmus this list of conditions and the following disclaimer in the documentation and/or 139949213aSStephan Aßmus other materials provided with the distribution. 149949213aSStephan Aßmus * Name "Marcin Konicki", "Shard" or any combination of them, 159949213aSStephan Aßmus must not be used to endorse or promote products derived from this 169949213aSStephan Aßmus software without specific prior written permission from Marcin Konicki. 179949213aSStephan Aßmus 189949213aSStephan Aßmus THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 199949213aSStephan Aßmus ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 209949213aSStephan Aßmus THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 219949213aSStephan Aßmus ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 229949213aSStephan Aßmus BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 239949213aSStephan Aßmus OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 249949213aSStephan Aßmus PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 259949213aSStephan Aßmus OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 269949213aSStephan Aßmus WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 279949213aSStephan Aßmus OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 289949213aSStephan Aßmus EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 299949213aSStephan Aßmus 309949213aSStephan Aßmus */ 319949213aSStephan Aßmus 329949213aSStephan Aßmus 339949213aSStephan Aßmus #include "JPEG2000Translator.h" 349949213aSStephan Aßmus #include "jp2_cod.h" 359949213aSStephan Aßmus #include "jpc_cs.h" 3694a204f0SStephan Aßmus #include "TranslatorWindow.h" 379949213aSStephan Aßmus 3894a204f0SStephan Aßmus #include <GroupLayoutBuilder.h> 39117da2d7SAxel Dörfler #include <TabView.h> 4094a204f0SStephan Aßmus #include <TextView.h> 41117da2d7SAxel Dörfler 429949213aSStephan Aßmus 43*c44966dfSJérôme Duval #undef B_TRANSLATE_CONTEXT 44*c44966dfSJérôme Duval #define B_TRANSLATE_CONTEXT "JPEG2000Translator" 45*c44966dfSJérôme Duval 469949213aSStephan Aßmus // Set these accordingly 479949213aSStephan Aßmus #define JP2_ACRONYM "JP2" 489949213aSStephan Aßmus #define JP2_FORMAT 'JP2 ' 499949213aSStephan Aßmus #define JP2_MIME_STRING "image/jp2" 509949213aSStephan Aßmus #define JP2_DESCRIPTION "JPEG2000 image" 519949213aSStephan Aßmus 529949213aSStephan Aßmus // The translation kit's native file type 539949213aSStephan Aßmus #define B_TRANSLATOR_BITMAP_MIME_STRING "image/x-be-bitmap" 54c095606eSRyan Leavengood #define B_TRANSLATOR_BITMAP_DESCRIPTION "Be Bitmap Format (JPEG2000Translator)" 559949213aSStephan Aßmus 56bf243977SPhilippe Houdoin static const char sTranslatorName[] = "JPEG2000 images"; 57bf243977SPhilippe Houdoin static const char sTranslatorInfo[] = "©2002-2003, Shard\n" 58117da2d7SAxel Dörfler "©2005-2006, Haiku\n" 59b0bc48fbSAxel Dörfler "\n" 60b0bc48fbSAxel Dörfler "Based on JasPer library:\n" 61b0bc48fbSAxel Dörfler "© 1999-2000, Image Power, Inc. and\n" 62b0bc48fbSAxel Dörfler "the University of British Columbia, Canada.\n" 63b0bc48fbSAxel Dörfler "© 2001-2003 Michael David Adams.\n" 64b0bc48fbSAxel Dörfler " http://www.ece.uvic.ca/~mdadams/jasper/\n" 65b0bc48fbSAxel Dörfler "\n" 66b0bc48fbSAxel Dörfler "ImageMagick's jp2 codec was used as \"tutorial\".\n" 67b0bc48fbSAxel Dörfler " http://www.imagemagick.org/\n"; 689949213aSStephan Aßmus 69bf243977SPhilippe Houdoin static int32 sTranslatorVersion = B_TRANSLATION_MAKE_VERSION(1, 0, 0); 709949213aSStephan Aßmus 71bf243977SPhilippe Houdoin static const translation_format sInputFormats[] = { 729949213aSStephan Aßmus { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5, 739949213aSStephan Aßmus JP2_MIME_STRING, JP2_DESCRIPTION }, 749949213aSStephan Aßmus { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5, 759949213aSStephan Aßmus B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION }, 769949213aSStephan Aßmus }; 779949213aSStephan Aßmus 78bf243977SPhilippe Houdoin static const translation_format sOutputFormats[] = { 799949213aSStephan Aßmus { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5, 809949213aSStephan Aßmus JP2_MIME_STRING, JP2_DESCRIPTION }, 819949213aSStephan Aßmus { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5, 829949213aSStephan Aßmus B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION }, 839949213aSStephan Aßmus }; 849949213aSStephan Aßmus 859949213aSStephan Aßmus 86bf243977SPhilippe Houdoin static const TranSetting sDefaultSettings[] = { 8794a204f0SStephan Aßmus {JP2_SET_QUALITY, TRAN_SETTING_INT32, 25}, 8894a204f0SStephan Aßmus {JP2_SET_JPC, TRAN_SETTING_BOOL, false}, 8994a204f0SStephan Aßmus {JP2_SET_GRAY1_AS_B_RGB24, TRAN_SETTING_BOOL, false}, 9094a204f0SStephan Aßmus {JP2_SET_GRAY8_AS_B_RGB32, TRAN_SETTING_BOOL, true} 9194a204f0SStephan Aßmus }; 92bf243977SPhilippe Houdoin 93bf243977SPhilippe Houdoin const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); 94bf243977SPhilippe Houdoin const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format); 95bf243977SPhilippe Houdoin const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting); 96117da2d7SAxel Dörfler 97117da2d7SAxel Dörfler 9894a204f0SStephan Aßmus namespace conversion{ 99117da2d7SAxel Dörfler //! Make RGB32 scanline from *pixels[3] 100117da2d7SAxel Dörfler inline void 101117da2d7SAxel Dörfler read_rgb24_to_rgb32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 102117da2d7SAxel Dörfler { 103117da2d7SAxel Dörfler int32 index = 0; 104117da2d7SAxel Dörfler int32 x = 0; 105117da2d7SAxel Dörfler while (x < width) { 106117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[2], x); 107117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[1], x); 108117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[0], x); 109117da2d7SAxel Dörfler scanline[index++] = 255; 110117da2d7SAxel Dörfler x++; 111117da2d7SAxel Dörfler } 112117da2d7SAxel Dörfler } 113117da2d7SAxel Dörfler 114117da2d7SAxel Dörfler 115117da2d7SAxel Dörfler //! Make gray scanline from *pixels[1] 116117da2d7SAxel Dörfler inline void 117117da2d7SAxel Dörfler read_gray_to_rgb32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 118117da2d7SAxel Dörfler { 119117da2d7SAxel Dörfler int32 index = 0; 120117da2d7SAxel Dörfler int32 x = 0; 121117da2d7SAxel Dörfler jpr_uchar_t color = 0; 122117da2d7SAxel Dörfler while (x < width) { 123117da2d7SAxel Dörfler color = (jpr_uchar_t)jas_matrix_getv(pixels[0], x++); 124117da2d7SAxel Dörfler scanline[index++] = color; 125117da2d7SAxel Dörfler scanline[index++] = color; 126117da2d7SAxel Dörfler scanline[index++] = color; 127117da2d7SAxel Dörfler scanline[index++] = 255; 128117da2d7SAxel Dörfler } 129117da2d7SAxel Dörfler } 130117da2d7SAxel Dörfler 131117da2d7SAxel Dörfler 132117da2d7SAxel Dörfler /*! 133117da2d7SAxel Dörfler Make RGBA32 scanline from *pixels[4] 134117da2d7SAxel Dörfler (just read data to scanline) 135117da2d7SAxel Dörfler */ 136117da2d7SAxel Dörfler inline void 137117da2d7SAxel Dörfler read_rgba32(jas_matrix_t** pixels, jpr_uchar_t *scanline, int width) 138117da2d7SAxel Dörfler { 139117da2d7SAxel Dörfler int32 index = 0; 140117da2d7SAxel Dörfler int32 x = 0; 141117da2d7SAxel Dörfler while (x < width) { 142117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[2], x); 143117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[1], x); 144117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[0], x); 145117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[3], x); 146117da2d7SAxel Dörfler x++; 147117da2d7SAxel Dörfler } 148117da2d7SAxel Dörfler } 149117da2d7SAxel Dörfler 150117da2d7SAxel Dörfler 151117da2d7SAxel Dörfler /*! 152117da2d7SAxel Dörfler Make gray scanline from *pixels[1] 153117da2d7SAxel Dörfler (just read data to scanline) 154117da2d7SAxel Dörfler */ 155117da2d7SAxel Dörfler inline void 156117da2d7SAxel Dörfler read_gray(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 157117da2d7SAxel Dörfler { 158117da2d7SAxel Dörfler int32 x = 0; 159117da2d7SAxel Dörfler while (x < width) { 160117da2d7SAxel Dörfler scanline[x] = (jpr_uchar_t)jas_matrix_getv(pixels[0], x); 161117da2d7SAxel Dörfler x++; 162117da2d7SAxel Dörfler } 163117da2d7SAxel Dörfler } 164117da2d7SAxel Dörfler 165117da2d7SAxel Dörfler 166117da2d7SAxel Dörfler //! Make *pixels[1] from gray1 scanline 167117da2d7SAxel Dörfler inline void 168117da2d7SAxel Dörfler write_gray1_to_gray(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 169117da2d7SAxel Dörfler { 170117da2d7SAxel Dörfler int32 x = 0; 171117da2d7SAxel Dörfler int32 index = 0; 172117da2d7SAxel Dörfler while (x < (width/8)) { 173117da2d7SAxel Dörfler unsigned char c = scanline[x++]; 174117da2d7SAxel Dörfler for (int b = 128; b; b = b >> 1) { 175117da2d7SAxel Dörfler if (c & b) 176117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index++, 0); 177117da2d7SAxel Dörfler else 178117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index++, 255); 179117da2d7SAxel Dörfler } 180117da2d7SAxel Dörfler } 181117da2d7SAxel Dörfler } 182117da2d7SAxel Dörfler 183117da2d7SAxel Dörfler 184117da2d7SAxel Dörfler //! Make *pixels[3] from gray1 scanline 185117da2d7SAxel Dörfler inline void 186117da2d7SAxel Dörfler write_gray1_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 187117da2d7SAxel Dörfler { 188117da2d7SAxel Dörfler int32 x = 0; 189117da2d7SAxel Dörfler int32 index = 0; 190117da2d7SAxel Dörfler while (x < (width / 8)) { 191117da2d7SAxel Dörfler unsigned char c = scanline[x++]; 192117da2d7SAxel Dörfler for (int b = 128; b; b = b >> 1) { 193117da2d7SAxel Dörfler if (c & b) { 194117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index, 0); 195117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], index, 0); 196117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], index, 0); 197117da2d7SAxel Dörfler } else { 198117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index, 255); 199117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], index, 255); 200117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], index, 255); 201117da2d7SAxel Dörfler } 202117da2d7SAxel Dörfler index++; 203117da2d7SAxel Dörfler } 204117da2d7SAxel Dörfler } 205117da2d7SAxel Dörfler } 206117da2d7SAxel Dörfler 207117da2d7SAxel Dörfler 208117da2d7SAxel Dörfler //! Make *pixels[3] from cmap8 scanline 209117da2d7SAxel Dörfler inline void 210117da2d7SAxel Dörfler write_cmap8_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 211117da2d7SAxel Dörfler { 212117da2d7SAxel Dörfler const color_map* map = system_colors(); 213117da2d7SAxel Dörfler int32 x = 0; 214117da2d7SAxel Dörfler while (x < width) { 215117da2d7SAxel Dörfler rgb_color color = map->color_list[scanline[x]]; 216117da2d7SAxel Dörfler 217117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, color.red); 218117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, color.green); 219117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, color.blue); 220117da2d7SAxel Dörfler x++; 221117da2d7SAxel Dörfler } 222117da2d7SAxel Dörfler } 223117da2d7SAxel Dörfler 224117da2d7SAxel Dörfler 225117da2d7SAxel Dörfler /*! 226117da2d7SAxel Dörfler Make *pixels[1] from gray scanline 227117da2d7SAxel Dörfler (just write data to pixels) 228117da2d7SAxel Dörfler */ 229117da2d7SAxel Dörfler inline void 230117da2d7SAxel Dörfler write_gray(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 231117da2d7SAxel Dörfler { 232117da2d7SAxel Dörfler int32 x = 0; 233117da2d7SAxel Dörfler while (x < width) { 234117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[x]); 235117da2d7SAxel Dörfler x++; 236117da2d7SAxel Dörfler } 237117da2d7SAxel Dörfler } 238117da2d7SAxel Dörfler 239117da2d7SAxel Dörfler 240117da2d7SAxel Dörfler /*! 241117da2d7SAxel Dörfler Make *pixels[3] from RGB15/RGBA15 scanline 242117da2d7SAxel Dörfler (just write data to pixels) 243117da2d7SAxel Dörfler */ 244117da2d7SAxel Dörfler inline void 245117da2d7SAxel Dörfler write_rgb15_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 246117da2d7SAxel Dörfler { 247117da2d7SAxel Dörfler int32 x = 0; 248117da2d7SAxel Dörfler int32 index = 0; 249117da2d7SAxel Dörfler int16 in_pixel; 250117da2d7SAxel Dörfler while (x < width) { 251117da2d7SAxel Dörfler in_pixel = scanline[index] | (scanline[index+1] << 8); 252117da2d7SAxel Dörfler index += 2; 253117da2d7SAxel Dörfler 25494a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7) 25594a204f0SStephan Aßmus | (((in_pixel & 0x7c00)) >> 12)); 25694a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2) 25794a204f0SStephan Aßmus | (((in_pixel & 0x3e0)) >> 7)); 25894a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 25994a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 260117da2d7SAxel Dörfler x++; 261117da2d7SAxel Dörfler } 262117da2d7SAxel Dörfler } 263117da2d7SAxel Dörfler 264117da2d7SAxel Dörfler 265117da2d7SAxel Dörfler /*! 266117da2d7SAxel Dörfler Make *pixels[3] from RGB15/RGBA15 bigendian scanline 267117da2d7SAxel Dörfler (just write data to pixels) 268117da2d7SAxel Dörfler */ 269117da2d7SAxel Dörfler inline void 270117da2d7SAxel Dörfler write_rgb15b_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 271117da2d7SAxel Dörfler { 272117da2d7SAxel Dörfler int32 x = 0; 273117da2d7SAxel Dörfler int32 index = 0; 274117da2d7SAxel Dörfler int16 in_pixel; 275117da2d7SAxel Dörfler while (x < width) { 276117da2d7SAxel Dörfler in_pixel = scanline[index + 1] | (scanline[index] << 8); 277117da2d7SAxel Dörfler index += 2; 278117da2d7SAxel Dörfler 27994a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7) 28094a204f0SStephan Aßmus | (((in_pixel & 0x7c00)) >> 12)); 28194a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2) 28294a204f0SStephan Aßmus | (((in_pixel & 0x3e0)) >> 7)); 28394a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 28494a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 285117da2d7SAxel Dörfler x++; 286117da2d7SAxel Dörfler } 287117da2d7SAxel Dörfler } 288117da2d7SAxel Dörfler 289117da2d7SAxel Dörfler 290117da2d7SAxel Dörfler /*! 291117da2d7SAxel Dörfler Make *pixels[3] from RGB16/RGBA16 scanline 292117da2d7SAxel Dörfler (just write data to pixels) 293117da2d7SAxel Dörfler */ 294117da2d7SAxel Dörfler inline void 295117da2d7SAxel Dörfler write_rgb16_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 296117da2d7SAxel Dörfler { 297117da2d7SAxel Dörfler int32 x = 0; 298117da2d7SAxel Dörfler int32 index = 0; 299117da2d7SAxel Dörfler int16 in_pixel; 300117da2d7SAxel Dörfler while (x < width) { 301117da2d7SAxel Dörfler in_pixel = scanline[index] | (scanline[index+1] << 8); 302117da2d7SAxel Dörfler index += 2; 303117da2d7SAxel Dörfler 30494a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8) 30594a204f0SStephan Aßmus | (((in_pixel & 0x7c00)) >> 12)); 30694a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3) 30794a204f0SStephan Aßmus | (((in_pixel & 0x7e0)) >> 9)); 30894a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 30994a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 310117da2d7SAxel Dörfler x++; 311117da2d7SAxel Dörfler } 312117da2d7SAxel Dörfler } 313117da2d7SAxel Dörfler 314117da2d7SAxel Dörfler 315117da2d7SAxel Dörfler /*! 316117da2d7SAxel Dörfler Make *pixels[3] from RGB16/RGBA16 bigendian scanline 317117da2d7SAxel Dörfler (just write data to pixels) 318117da2d7SAxel Dörfler */ 319117da2d7SAxel Dörfler inline void 320117da2d7SAxel Dörfler write_rgb16b_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 321117da2d7SAxel Dörfler { 322117da2d7SAxel Dörfler int32 x = 0; 323117da2d7SAxel Dörfler int32 index = 0; 324117da2d7SAxel Dörfler int16 in_pixel; 325117da2d7SAxel Dörfler while (x < width) { 326117da2d7SAxel Dörfler in_pixel = scanline[index + 1] | (scanline[index] << 8); 327117da2d7SAxel Dörfler index += 2; 328117da2d7SAxel Dörfler 32994a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8) 33094a204f0SStephan Aßmus | (((in_pixel & 0xf800)) >> 13)); 33194a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3) 33294a204f0SStephan Aßmus | (((in_pixel & 0x7e0)) >> 9)); 33394a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 33494a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 335117da2d7SAxel Dörfler x++; 336117da2d7SAxel Dörfler } 337117da2d7SAxel Dörfler } 338117da2d7SAxel Dörfler 339117da2d7SAxel Dörfler 340117da2d7SAxel Dörfler /*! 341117da2d7SAxel Dörfler Make *pixels[3] from RGB24 scanline 342117da2d7SAxel Dörfler (just write data to pixels) 343117da2d7SAxel Dörfler */ 344117da2d7SAxel Dörfler inline void 345117da2d7SAxel Dörfler write_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 346117da2d7SAxel Dörfler { 347117da2d7SAxel Dörfler int32 index = 0; 348117da2d7SAxel Dörfler int32 x = 0; 349117da2d7SAxel Dörfler while (x < width) { 350117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 351117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 352117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 353117da2d7SAxel Dörfler x++; 354117da2d7SAxel Dörfler } 355117da2d7SAxel Dörfler } 356117da2d7SAxel Dörfler 357117da2d7SAxel Dörfler 358117da2d7SAxel Dörfler /*! 359117da2d7SAxel Dörfler Make *pixels[3] from RGB24 bigendian scanline 360117da2d7SAxel Dörfler (just write data to pixels) 361117da2d7SAxel Dörfler */ 362117da2d7SAxel Dörfler inline void 363117da2d7SAxel Dörfler write_rgb24b(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 364117da2d7SAxel Dörfler { 365117da2d7SAxel Dörfler int32 index = 0; 366117da2d7SAxel Dörfler int32 x = 0; 367117da2d7SAxel Dörfler while (x < width) { 368117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 369117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 370117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 371117da2d7SAxel Dörfler x++; 372117da2d7SAxel Dörfler } 373117da2d7SAxel Dörfler } 374117da2d7SAxel Dörfler 375117da2d7SAxel Dörfler 376117da2d7SAxel Dörfler /*! 377117da2d7SAxel Dörfler Make *pixels[3] from RGB32 scanline 378117da2d7SAxel Dörfler (just write data to pixels) 379117da2d7SAxel Dörfler */ 380117da2d7SAxel Dörfler inline void 381117da2d7SAxel Dörfler write_rgb32_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 382117da2d7SAxel Dörfler { 383117da2d7SAxel Dörfler int32 index = 0; 384117da2d7SAxel Dörfler int32 x = 0; 385117da2d7SAxel Dörfler while (x < width) { 386117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 387117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 388117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 389117da2d7SAxel Dörfler index++; 390117da2d7SAxel Dörfler x++; 391117da2d7SAxel Dörfler } 392117da2d7SAxel Dörfler } 393117da2d7SAxel Dörfler 394117da2d7SAxel Dörfler 395117da2d7SAxel Dörfler /*! 396117da2d7SAxel Dörfler Make *pixels[3] from RGB32 bigendian scanline 397117da2d7SAxel Dörfler (just write data to pixels) 398117da2d7SAxel Dörfler */ 399117da2d7SAxel Dörfler inline void 400117da2d7SAxel Dörfler write_rgb32b_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 401117da2d7SAxel Dörfler { 402117da2d7SAxel Dörfler int32 index = 0; 403117da2d7SAxel Dörfler int32 x = 0; 404117da2d7SAxel Dörfler while (x < width) { 405117da2d7SAxel Dörfler index++; 406117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 407117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 408117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 409117da2d7SAxel Dörfler x++; 410117da2d7SAxel Dörfler } 411117da2d7SAxel Dörfler } 412117da2d7SAxel Dörfler 413117da2d7SAxel Dörfler 414117da2d7SAxel Dörfler /*! 415117da2d7SAxel Dörfler Make *pixels[4] from RGBA32 scanline 416117da2d7SAxel Dörfler (just write data to pixels) 417117da2d7SAxel Dörfler !!! UNTESTED !!! 418117da2d7SAxel Dörfler */ 419117da2d7SAxel Dörfler inline void 420117da2d7SAxel Dörfler write_rgba32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 421117da2d7SAxel Dörfler { 422117da2d7SAxel Dörfler int32 index = 0; 423117da2d7SAxel Dörfler int32 x = 0; 424117da2d7SAxel Dörfler while (x < width) { 425117da2d7SAxel Dörfler jas_matrix_setv(pixels[3], x, scanline[index++]); 426117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 427117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 428117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 429117da2d7SAxel Dörfler x++; 430117da2d7SAxel Dörfler } 431117da2d7SAxel Dörfler } 432117da2d7SAxel Dörfler 433117da2d7SAxel Dörfler 434117da2d7SAxel Dörfler /*! 435117da2d7SAxel Dörfler Make *pixels[4] from RGBA32 bigendian scanline 436117da2d7SAxel Dörfler (just write data to pixels) 437117da2d7SAxel Dörfler !!! UNTESTED !!! 438117da2d7SAxel Dörfler */ 439117da2d7SAxel Dörfler inline void 440117da2d7SAxel Dörfler write_rgba32b(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 441117da2d7SAxel Dörfler { 442117da2d7SAxel Dörfler int32 index = 0; 443117da2d7SAxel Dörfler int32 x = 0; 444117da2d7SAxel Dörfler while (x < width) 445117da2d7SAxel Dörfler { 446117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 447117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 448117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 449117da2d7SAxel Dörfler jas_matrix_setv(pixels[3], x, scanline[index++]); 450117da2d7SAxel Dörfler x++; 451117da2d7SAxel Dörfler } 452117da2d7SAxel Dörfler } 453117da2d7SAxel Dörfler 454117da2d7SAxel Dörfler 45594a204f0SStephan Aßmus }// end namespace conversion 45694a204f0SStephan Aßmus 45794a204f0SStephan Aßmus 458117da2d7SAxel Dörfler // #pragma mark - jasper I/O 459117da2d7SAxel Dörfler 460117da2d7SAxel Dörfler 461117da2d7SAxel Dörfler static int 462117da2d7SAxel Dörfler Read(jas_stream_obj_t* object, char* buffer, const int length) 4639949213aSStephan Aßmus { 4649949213aSStephan Aßmus return (*(BPositionIO**)object)->Read(buffer, length); 4659949213aSStephan Aßmus } 4669949213aSStephan Aßmus 467117da2d7SAxel Dörfler 468117da2d7SAxel Dörfler static int 469117da2d7SAxel Dörfler Write(jas_stream_obj_t* object, char* buffer, const int length) 4709949213aSStephan Aßmus { 4719949213aSStephan Aßmus return (*(BPositionIO**)object)->Write(buffer, length); 4729949213aSStephan Aßmus } 4739949213aSStephan Aßmus 474117da2d7SAxel Dörfler 475117da2d7SAxel Dörfler static long 476117da2d7SAxel Dörfler Seek(jas_stream_obj_t* object, long offset, int origin) 4779949213aSStephan Aßmus { 4789949213aSStephan Aßmus return (*(BPositionIO**)object)->Seek(offset, origin); 4799949213aSStephan Aßmus } 4809949213aSStephan Aßmus 481117da2d7SAxel Dörfler 482117da2d7SAxel Dörfler static int 483117da2d7SAxel Dörfler Close(jas_stream_obj_t* object) 4849949213aSStephan Aßmus { 485117da2d7SAxel Dörfler return 0; 4869949213aSStephan Aßmus } 4879949213aSStephan Aßmus 488117da2d7SAxel Dörfler 489117da2d7SAxel Dörfler static jas_stream_ops_t positionIOops = { 4909949213aSStephan Aßmus Read, 4919949213aSStephan Aßmus Write, 4929949213aSStephan Aßmus Seek, 4939949213aSStephan Aßmus Close 4949949213aSStephan Aßmus }; 4959949213aSStephan Aßmus 496117da2d7SAxel Dörfler 497117da2d7SAxel Dörfler static jas_stream_t* 498117da2d7SAxel Dörfler jas_stream_positionIOopen(BPositionIO *positionIO) 4999949213aSStephan Aßmus { 5009949213aSStephan Aßmus jas_stream_t* stream; 5019949213aSStephan Aßmus 5029949213aSStephan Aßmus stream = (jas_stream_t *)malloc(sizeof(jas_stream_t)); 5039949213aSStephan Aßmus if (stream == (jas_stream_t *)NULL) 504117da2d7SAxel Dörfler return (jas_stream_t *)NULL; 505117da2d7SAxel Dörfler 506117da2d7SAxel Dörfler memset(stream, 0, sizeof(jas_stream_t)); 507117da2d7SAxel Dörfler stream->rwlimit_ = -1; 5089949213aSStephan Aßmus stream->obj_=(jas_stream_obj_t *)malloc(sizeof(BPositionIO*)); 50913eaf8faSStephan Aßmus if (stream->obj_ == (jas_stream_obj_t *)NULL) { 51013eaf8faSStephan Aßmus free(stream); 511117da2d7SAxel Dörfler return (jas_stream_t *)NULL; 51213eaf8faSStephan Aßmus } 513117da2d7SAxel Dörfler 5149949213aSStephan Aßmus *((BPositionIO**)stream->obj_) = positionIO; 5159949213aSStephan Aßmus stream->ops_ = (&positionIOops); 5169949213aSStephan Aßmus stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; 5179949213aSStephan Aßmus stream->bufbase_ = stream->tinybuf_; 5189949213aSStephan Aßmus stream->bufsize_ = 1; 5199949213aSStephan Aßmus stream->bufstart_ = (&stream->bufbase_[JAS_STREAM_MAXPUTBACK]); 5209949213aSStephan Aßmus stream->ptr_ = stream->bufstart_; 5219949213aSStephan Aßmus stream->bufmode_ |= JAS_STREAM_UNBUF & JAS_STREAM_BUFMODEMASK; 522117da2d7SAxel Dörfler 523117da2d7SAxel Dörfler return stream; 5249949213aSStephan Aßmus } 5259949213aSStephan Aßmus 5269949213aSStephan Aßmus 527117da2d7SAxel Dörfler // #pragma mark - 528117da2d7SAxel Dörfler 529117da2d7SAxel Dörfler 53094a204f0SStephan Aßmus SSlider::SSlider(const char* name, const char* label, 531117da2d7SAxel Dörfler BMessage* message, int32 minValue, int32 maxValue, orientation posture, 53294a204f0SStephan Aßmus thumb_style thumbType, uint32 flags) 53394a204f0SStephan Aßmus : 53494a204f0SStephan Aßmus BSlider(name, label, message, minValue, maxValue, 53594a204f0SStephan Aßmus posture, thumbType, flags) 536117da2d7SAxel Dörfler { 537117da2d7SAxel Dörfler rgb_color barColor = { 0, 0, 229, 255 }; 538117da2d7SAxel Dörfler UseFillColor(true, &barColor); 539117da2d7SAxel Dörfler } 540117da2d7SAxel Dörfler 541117da2d7SAxel Dörfler 542117da2d7SAxel Dörfler //! Update status string - show actual value 5436bda235aSStefano Ceccherini const char* 5449949213aSStephan Aßmus SSlider::UpdateText() const 5459949213aSStephan Aßmus { 546117da2d7SAxel Dörfler snprintf(fStatusLabel, sizeof(fStatusLabel), "%ld", Value()); 547117da2d7SAxel Dörfler return fStatusLabel; 5489949213aSStephan Aßmus } 5499949213aSStephan Aßmus 550117da2d7SAxel Dörfler 551117da2d7SAxel Dörfler // #pragma mark - 5529949213aSStephan Aßmus 553117da2d7SAxel Dörfler 55494a204f0SStephan Aßmus TranslatorReadView::TranslatorReadView(const char* name, 55594a204f0SStephan Aßmus TranslatorSettings* settings) 55694a204f0SStephan Aßmus : 55794a204f0SStephan Aßmus BView(name, 0, new BGroupLayout(B_VERTICAL)), 558117da2d7SAxel Dörfler fSettings(settings) 5599949213aSStephan Aßmus { 56094a204f0SStephan Aßmus fGrayAsRGB32 = new BCheckBox("grayasrgb32", VIEW_LABEL_GRAYASRGB32, 56194a204f0SStephan Aßmus new BMessage(VIEW_MSG_SET_GRAYASRGB32)); 56294a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) 56394a204f0SStephan Aßmus fGrayAsRGB32->SetValue(B_CONTROL_ON); 5649949213aSStephan Aßmus 56594a204f0SStephan Aßmus float padding = 10.0f; 56694a204f0SStephan Aßmus AddChild(BGroupLayoutBuilder(B_VERTICAL) 56794a204f0SStephan Aßmus .Add(fGrayAsRGB32) 56894a204f0SStephan Aßmus .AddGlue() 56994a204f0SStephan Aßmus .SetInsets(padding, padding, padding, padding) 57094a204f0SStephan Aßmus ); 57194a204f0SStephan Aßmus } 57294a204f0SStephan Aßmus 57394a204f0SStephan Aßmus 57494a204f0SStephan Aßmus TranslatorReadView::~TranslatorReadView() 57594a204f0SStephan Aßmus { 57694a204f0SStephan Aßmus fSettings->Release(); 5779949213aSStephan Aßmus } 5789949213aSStephan Aßmus 579117da2d7SAxel Dörfler 5809949213aSStephan Aßmus void 5819949213aSStephan Aßmus TranslatorReadView::AttachedToWindow() 5829949213aSStephan Aßmus { 583117da2d7SAxel Dörfler fGrayAsRGB32->SetTarget(this); 5849949213aSStephan Aßmus } 5859949213aSStephan Aßmus 586117da2d7SAxel Dörfler 5879949213aSStephan Aßmus void 5889949213aSStephan Aßmus TranslatorReadView::MessageReceived(BMessage* message) 5899949213aSStephan Aßmus { 590117da2d7SAxel Dörfler switch (message->what) { 5919949213aSStephan Aßmus case VIEW_MSG_SET_GRAYASRGB32: 5929949213aSStephan Aßmus { 5939949213aSStephan Aßmus int32 value; 5949949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 59594a204f0SStephan Aßmus bool boolValue = value; 59694a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32, &boolValue); 59794a204f0SStephan Aßmus fSettings->SaveSettings(); 5989949213aSStephan Aßmus } 5999949213aSStephan Aßmus break; 6009949213aSStephan Aßmus } 6019949213aSStephan Aßmus default: 6029949213aSStephan Aßmus BView::MessageReceived(message); 6039949213aSStephan Aßmus break; 6049949213aSStephan Aßmus } 6059949213aSStephan Aßmus } 6069949213aSStephan Aßmus 6079949213aSStephan Aßmus 608117da2d7SAxel Dörfler // #pragma mark - TranslatorWriteView 6099949213aSStephan Aßmus 610117da2d7SAxel Dörfler 61194a204f0SStephan Aßmus TranslatorWriteView::TranslatorWriteView(const char* name, 61294a204f0SStephan Aßmus TranslatorSettings* settings) 61394a204f0SStephan Aßmus : 61494a204f0SStephan Aßmus BView(name, 0, new BGroupLayout(B_VERTICAL)), 615117da2d7SAxel Dörfler fSettings(settings) 6169949213aSStephan Aßmus { 61794a204f0SStephan Aßmus fQualitySlider = new SSlider("quality", VIEW_LABEL_QUALITY, 61894a204f0SStephan Aßmus new BMessage(VIEW_MSG_SET_QUALITY), 0, 100); 619117da2d7SAxel Dörfler fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM); 620117da2d7SAxel Dörfler fQualitySlider->SetHashMarkCount(10); 621*c44966dfSJérôme Duval fQualitySlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High")); 62294a204f0SStephan Aßmus fQualitySlider->SetValue(fSettings->SetGetInt32(JP2_SET_QUALITY)); 6239949213aSStephan Aßmus 62494a204f0SStephan Aßmus fGrayAsRGB24 = new BCheckBox("gray1asrgb24", VIEW_LABEL_GRAY1ASRGB24, 625117da2d7SAxel Dörfler new BMessage(VIEW_MSG_SET_GRAY1ASRGB24)); 62694a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) 62794a204f0SStephan Aßmus fGrayAsRGB24->SetValue(B_CONTROL_ON); 6289949213aSStephan Aßmus 62994a204f0SStephan Aßmus fCodeStreamOnly = new BCheckBox("codestreamonly", VIEW_LABEL_JPC, 63094a204f0SStephan Aßmus new BMessage(VIEW_MSG_SET_JPC)); 63194a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_JPC)) 63294a204f0SStephan Aßmus fCodeStreamOnly->SetValue(B_CONTROL_ON); 6339949213aSStephan Aßmus 63494a204f0SStephan Aßmus float padding = 10.0f; 63594a204f0SStephan Aßmus AddChild(BGroupLayoutBuilder(B_VERTICAL, padding) 63694a204f0SStephan Aßmus .Add(fQualitySlider) 63794a204f0SStephan Aßmus .Add(fGrayAsRGB24) 63894a204f0SStephan Aßmus .Add(fCodeStreamOnly) 63994a204f0SStephan Aßmus .AddGlue() 64094a204f0SStephan Aßmus .SetInsets(padding, padding, padding, padding) 64194a204f0SStephan Aßmus ); 64294a204f0SStephan Aßmus } 643bdaaeb0cSStefano Ceccherini 6449949213aSStephan Aßmus 64594a204f0SStephan Aßmus TranslatorWriteView::~TranslatorWriteView() 64694a204f0SStephan Aßmus { 64794a204f0SStephan Aßmus fSettings->Release(); 6489949213aSStephan Aßmus } 6499949213aSStephan Aßmus 650117da2d7SAxel Dörfler 6519949213aSStephan Aßmus void 6529949213aSStephan Aßmus TranslatorWriteView::AttachedToWindow() 6539949213aSStephan Aßmus { 654117da2d7SAxel Dörfler fQualitySlider->SetTarget(this); 655117da2d7SAxel Dörfler fGrayAsRGB24->SetTarget(this); 656117da2d7SAxel Dörfler fCodeStreamOnly->SetTarget(this); 6579949213aSStephan Aßmus } 6589949213aSStephan Aßmus 659117da2d7SAxel Dörfler 6609949213aSStephan Aßmus void 6619949213aSStephan Aßmus TranslatorWriteView::MessageReceived(BMessage* message) 6629949213aSStephan Aßmus { 663117da2d7SAxel Dörfler switch (message->what) { 6649949213aSStephan Aßmus case VIEW_MSG_SET_QUALITY: 6659949213aSStephan Aßmus { 6669949213aSStephan Aßmus int32 value; 6679949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 66894a204f0SStephan Aßmus fSettings->SetGetInt32(JP2_SET_QUALITY, &value); 66994a204f0SStephan Aßmus fSettings->SaveSettings(); 6709949213aSStephan Aßmus } 6719949213aSStephan Aßmus break; 6729949213aSStephan Aßmus } 6739949213aSStephan Aßmus case VIEW_MSG_SET_GRAY1ASRGB24: 6749949213aSStephan Aßmus { 6759949213aSStephan Aßmus int32 value; 6769949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 67794a204f0SStephan Aßmus bool boolValue = value; 67894a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24, &boolValue); 67994a204f0SStephan Aßmus fSettings->SaveSettings(); 6809949213aSStephan Aßmus } 6819949213aSStephan Aßmus break; 6829949213aSStephan Aßmus } 6839949213aSStephan Aßmus case VIEW_MSG_SET_JPC: 6849949213aSStephan Aßmus { 6859949213aSStephan Aßmus int32 value; 6869949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 68794a204f0SStephan Aßmus bool boolValue = value; 68894a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_JPC, &boolValue); 68994a204f0SStephan Aßmus fSettings->SaveSettings(); 6909949213aSStephan Aßmus } 6919949213aSStephan Aßmus break; 6929949213aSStephan Aßmus } 6939949213aSStephan Aßmus default: 6949949213aSStephan Aßmus BView::MessageReceived(message); 6959949213aSStephan Aßmus break; 6969949213aSStephan Aßmus } 6979949213aSStephan Aßmus } 6989949213aSStephan Aßmus 6999949213aSStephan Aßmus 700117da2d7SAxel Dörfler // #pragma mark - 7019949213aSStephan Aßmus 702117da2d7SAxel Dörfler 70394a204f0SStephan Aßmus TranslatorAboutView::TranslatorAboutView(const char* name) 70494a204f0SStephan Aßmus : 70594a204f0SStephan Aßmus BView(name, 0, new BGroupLayout(B_VERTICAL)) 7069949213aSStephan Aßmus { 70794a204f0SStephan Aßmus BAlignment labelAlignment = BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP); 708bf243977SPhilippe Houdoin BStringView* title = new BStringView("Title", sTranslatorName); 709*c44966dfSJérôme Duval title->SetText(B_TRANSLATE_MARK("JPEG2000 images")); 7109949213aSStephan Aßmus title->SetFont(be_bold_font); 71194a204f0SStephan Aßmus title->SetExplicitAlignment(labelAlignment); 7129949213aSStephan Aßmus 7139949213aSStephan Aßmus char versionString[16]; 714*c44966dfSJérôme Duval sprintf(versionString, "v%d.%d.%d", 715*c44966dfSJérôme Duval static_cast<int>(sTranslatorVersion >> 8), 716*c44966dfSJérôme Duval static_cast<int>((sTranslatorVersion >> 4) & 0xf), 717*c44966dfSJérôme Duval static_cast<int>(sTranslatorVersion & 0xf)); 7189949213aSStephan Aßmus 71994a204f0SStephan Aßmus BStringView* version = new BStringView("Version", versionString); 72094a204f0SStephan Aßmus version->SetExplicitAlignment(labelAlignment); 7219949213aSStephan Aßmus 72294a204f0SStephan Aßmus BTextView* infoView = new BTextView("info"); 723*c44966dfSJérôme Duval BString translationInfo(sTranslatorInfo); 724*c44966dfSJérôme Duval translationInfo.ReplaceFirst("Based on JasPer library:", 725*c44966dfSJérôme Duval B_TRANSLATE("Based on JasPer library:")); 726*c44966dfSJérôme Duval translationInfo.ReplaceFirst("1999-2000, Image Power, Inc. and", 727*c44966dfSJérôme Duval B_TRANSLATE("1999-2000, Image Power, Inc. and")); 728*c44966dfSJérôme Duval translationInfo.ReplaceFirst("the University of British Columbia, Canada.", 729*c44966dfSJérôme Duval B_TRANSLATE("the University of British Columbia, Canada.")); 730*c44966dfSJérôme Duval translationInfo.ReplaceFirst("ImageMagick's jp2 codec was used as " 731*c44966dfSJérôme Duval "\"tutorial\".", B_TRANSLATE("ImageMagick's jp2 codec was used as " 732*c44966dfSJérôme Duval "\"tutorial\".")); 733*c44966dfSJérôme Duval infoView->SetText(translationInfo.String()); 73494a204f0SStephan Aßmus infoView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 73594a204f0SStephan Aßmus infoView->MakeEditable(false); 7369949213aSStephan Aßmus 73794a204f0SStephan Aßmus float padding = 10.0f; 73894a204f0SStephan Aßmus AddChild(BGroupLayoutBuilder(B_VERTICAL, padding) 73994a204f0SStephan Aßmus .Add(BGroupLayoutBuilder(B_HORIZONTAL, padding) 74094a204f0SStephan Aßmus .Add(title) 74194a204f0SStephan Aßmus .Add(version) 74294a204f0SStephan Aßmus .AddGlue() 74394a204f0SStephan Aßmus ) 74494a204f0SStephan Aßmus .Add(infoView) 74594a204f0SStephan Aßmus .SetInsets(padding, padding, padding, padding) 74694a204f0SStephan Aßmus ); 7479949213aSStephan Aßmus } 7489949213aSStephan Aßmus 7499949213aSStephan Aßmus 750117da2d7SAxel Dörfler // #pragma mark - 7519949213aSStephan Aßmus 752117da2d7SAxel Dörfler 75394a204f0SStephan Aßmus TranslatorView::TranslatorView(const char* name, TranslatorSettings* settings) 75494a204f0SStephan Aßmus : 75594a204f0SStephan Aßmus BTabView(name) 7569949213aSStephan Aßmus { 757*c44966dfSJérôme Duval AddTab(new TranslatorWriteView(B_TRANSLATE("Write"), 758*c44966dfSJérôme Duval settings->Acquire())); 759*c44966dfSJérôme Duval AddTab(new TranslatorReadView(B_TRANSLATE("Read"), 760*c44966dfSJérôme Duval settings->Acquire())); 761*c44966dfSJérôme Duval AddTab(new TranslatorAboutView(B_TRANSLATE("About"))); 7629949213aSStephan Aßmus 76394a204f0SStephan Aßmus settings->Release(); 7649949213aSStephan Aßmus 76594a204f0SStephan Aßmus BFont font; 76694a204f0SStephan Aßmus GetFont(&font); 76794a204f0SStephan Aßmus SetExplicitPreferredSize( 76894a204f0SStephan Aßmus BSize((font.Size() * 380) / 12, (font.Size() * 250) / 12)); 7699949213aSStephan Aßmus } 7709949213aSStephan Aßmus 7719949213aSStephan Aßmus 772117da2d7SAxel Dörfler // #pragma mark - 7739949213aSStephan Aßmus 77494a204f0SStephan Aßmus BView* 77594a204f0SStephan Aßmus JP2Translator::NewConfigView(TranslatorSettings* settings) 7769949213aSStephan Aßmus { 77794a204f0SStephan Aßmus BView* outView = new TranslatorView("TranslatorView", settings); 77894a204f0SStephan Aßmus return outView; 7799949213aSStephan Aßmus } 7809949213aSStephan Aßmus 7819949213aSStephan Aßmus 78294a204f0SStephan Aßmus JP2Translator::JP2Translator() 783bf243977SPhilippe Houdoin : BaseTranslator(sTranslatorName, sTranslatorInfo, sTranslatorVersion, 784bf243977SPhilippe Houdoin sInputFormats, kNumInputFormats, 785bf243977SPhilippe Houdoin sOutputFormats, kNumOutputFormats, 786bf243977SPhilippe Houdoin JP2_SETTINGS_FILE, 787bf243977SPhilippe Houdoin sDefaultSettings, kNumDefaultSettings, 788bf243977SPhilippe Houdoin B_TRANSLATOR_BITMAP, JP2_FORMAT) 7899949213aSStephan Aßmus { 7909949213aSStephan Aßmus } 7919949213aSStephan Aßmus 792117da2d7SAxel Dörfler 793117da2d7SAxel Dörfler //! Determine whether or not we can handle this data 7949949213aSStephan Aßmus status_t 79594a204f0SStephan Aßmus JP2Translator::DerivedIdentify(BPositionIO* inSource, 79694a204f0SStephan Aßmus const translation_format* inFormat, BMessage* ioExtension, 79794a204f0SStephan Aßmus translator_info* outInfo, uint32 outType) 7989949213aSStephan Aßmus { 79913eaf8faSStephan Aßmus if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP) 80013eaf8faSStephan Aßmus && outType != JP2_FORMAT) 8019949213aSStephan Aßmus return B_NO_TRANSLATOR; 8029949213aSStephan Aßmus 80313eaf8faSStephan Aßmus // !!! You might need to make this buffer bigger to test for your 80413eaf8faSStephan Aßmus // native format 8059949213aSStephan Aßmus off_t position = inSource->Position(); 8069949213aSStephan Aßmus uint8 header[sizeof(TranslatorBitmap)]; 8079949213aSStephan Aßmus status_t err = inSource->Read(header, sizeof(TranslatorBitmap)); 8089949213aSStephan Aßmus inSource->Seek(position, SEEK_SET); 809117da2d7SAxel Dörfler if (err < B_OK) 810117da2d7SAxel Dörfler return err; 8119949213aSStephan Aßmus 81213eaf8faSStephan Aßmus if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic) 81313eaf8faSStephan Aßmus == B_TRANSLATOR_BITMAP) { 81494a204f0SStephan Aßmus if (PopulateInfoFromFormat(outInfo, B_TRANSLATOR_BITMAP) != B_OK) 81594a204f0SStephan Aßmus return B_NO_TRANSLATOR; 8169949213aSStephan Aßmus } else { 81713eaf8faSStephan Aßmus if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8) 81813eaf8faSStephan Aßmus | header[7]) == JP2_BOX_JP) // JP2 81913eaf8faSStephan Aßmus || (header[0] == (JPC_MS_SOC >> 8) && header[1] 82013eaf8faSStephan Aßmus == (JPC_MS_SOC & 0xff))) // JPC 8219949213aSStephan Aßmus { 82294a204f0SStephan Aßmus if (PopulateInfoFromFormat(outInfo, JP2_FORMAT) != B_OK) 82394a204f0SStephan Aßmus return B_NO_TRANSLATOR; 8249949213aSStephan Aßmus } else 8259949213aSStephan Aßmus return B_NO_TRANSLATOR; 8269949213aSStephan Aßmus } 8279949213aSStephan Aßmus 8289949213aSStephan Aßmus return B_OK; 8299949213aSStephan Aßmus } 8309949213aSStephan Aßmus 831117da2d7SAxel Dörfler 8329949213aSStephan Aßmus status_t 83394a204f0SStephan Aßmus JP2Translator::DerivedTranslate(BPositionIO* inSource, 83494a204f0SStephan Aßmus const translator_info* inInfo, BMessage* ioExtension, uint32 outType, 83594a204f0SStephan Aßmus BPositionIO* outDestination, int32 baseType) 8369949213aSStephan Aßmus { 8379949213aSStephan Aßmus // If no specific type was requested, convert to the interchange format 838117da2d7SAxel Dörfler if (outType == 0) 839117da2d7SAxel Dörfler outType = B_TRANSLATOR_BITMAP; 8409949213aSStephan Aßmus 8419949213aSStephan Aßmus // What action to take, based on the findings of Identify() 842117da2d7SAxel Dörfler if (outType == inInfo->type) 8439949213aSStephan Aßmus return Copy(inSource, outDestination); 844117da2d7SAxel Dörfler if (inInfo->type == B_TRANSLATOR_BITMAP && outType == JP2_FORMAT) 8459949213aSStephan Aßmus return Compress(inSource, outDestination); 846117da2d7SAxel Dörfler if (inInfo->type == JP2_FORMAT && outType == B_TRANSLATOR_BITMAP) 8479949213aSStephan Aßmus return Decompress(inSource, outDestination); 8489949213aSStephan Aßmus 8499949213aSStephan Aßmus return B_NO_TRANSLATOR; 8509949213aSStephan Aßmus } 8519949213aSStephan Aßmus 852117da2d7SAxel Dörfler 853117da2d7SAxel Dörfler //! The user has requested the same format for input and output, so just copy 8549949213aSStephan Aßmus status_t 85594a204f0SStephan Aßmus JP2Translator::Copy(BPositionIO* in, BPositionIO* out) 8569949213aSStephan Aßmus { 8579949213aSStephan Aßmus int block_size = 65536; 8589949213aSStephan Aßmus void* buffer = malloc(block_size); 8599949213aSStephan Aßmus char temp[1024]; 8609949213aSStephan Aßmus if (buffer == NULL) { 8619949213aSStephan Aßmus buffer = temp; 8629949213aSStephan Aßmus block_size = 1024; 8639949213aSStephan Aßmus } 8649949213aSStephan Aßmus status_t err = B_OK; 8659949213aSStephan Aßmus 8669949213aSStephan Aßmus // Read until end of file or error 8679949213aSStephan Aßmus while (1) { 8689949213aSStephan Aßmus ssize_t to_read = block_size; 8699949213aSStephan Aßmus err = in->Read(buffer, to_read); 8709949213aSStephan Aßmus // Explicit check for EOF 8719949213aSStephan Aßmus if (err == -1) { 872117da2d7SAxel Dörfler if (buffer != temp) 873117da2d7SAxel Dörfler free(buffer); 8749949213aSStephan Aßmus return B_OK; 8759949213aSStephan Aßmus } 8769949213aSStephan Aßmus if (err <= B_OK) break; 8779949213aSStephan Aßmus to_read = err; 8789949213aSStephan Aßmus err = out->Write(buffer, to_read); 8799949213aSStephan Aßmus if (err != to_read) if (err >= 0) err = B_DEVICE_FULL; 8809949213aSStephan Aßmus if (err < B_OK) break; 8819949213aSStephan Aßmus } 8829949213aSStephan Aßmus 883117da2d7SAxel Dörfler if (buffer != temp) 884117da2d7SAxel Dörfler free(buffer); 8859949213aSStephan Aßmus return (err >= 0) ? B_OK : err; 8869949213aSStephan Aßmus } 8879949213aSStephan Aßmus 888117da2d7SAxel Dörfler 889117da2d7SAxel Dörfler //! Encode into the native format 8909949213aSStephan Aßmus status_t 89194a204f0SStephan Aßmus JP2Translator::Compress(BPositionIO* in, BPositionIO* out) 8929949213aSStephan Aßmus { 89394a204f0SStephan Aßmus using namespace conversion; 8949949213aSStephan Aßmus 8959949213aSStephan Aßmus // Read info about bitmap 8969949213aSStephan Aßmus TranslatorBitmap header; 8979949213aSStephan Aßmus status_t err = in->Read(&header, sizeof(TranslatorBitmap)); 898117da2d7SAxel Dörfler if (err < B_OK) 899117da2d7SAxel Dörfler return err; 900117da2d7SAxel Dörfler if (err < (int)sizeof(TranslatorBitmap)) 901117da2d7SAxel Dörfler return B_ERROR; 9029949213aSStephan Aßmus 9039949213aSStephan Aßmus // Grab dimension, color space, and size information from the stream 9049949213aSStephan Aßmus BRect bounds; 9059949213aSStephan Aßmus bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left); 9069949213aSStephan Aßmus bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top); 9079949213aSStephan Aßmus bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right); 9089949213aSStephan Aßmus bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom); 9099949213aSStephan Aßmus 9109949213aSStephan Aßmus int32 in_row_bytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes); 9119949213aSStephan Aßmus 9129949213aSStephan Aßmus int width = bounds.IntegerWidth() + 1; 9139949213aSStephan Aßmus int height = bounds.IntegerHeight() + 1; 9149949213aSStephan Aßmus 9159949213aSStephan Aßmus // Function pointer to write function 9169949213aSStephan Aßmus // It MUST point to proper function 91713eaf8faSStephan Aßmus void (*converter)(jas_matrix_t** pixels, jpr_uchar_t* inscanline, 91813eaf8faSStephan Aßmus int width) = write_rgba32; 9199949213aSStephan Aßmus 9209949213aSStephan Aßmus // Default color info 9219949213aSStephan Aßmus int out_color_space = JAS_IMAGE_CS_RGB; 9229949213aSStephan Aßmus int out_color_components = 3; 9239949213aSStephan Aßmus 924117da2d7SAxel Dörfler switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) { 9259949213aSStephan Aßmus case B_GRAY1: 92694a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) { 9279949213aSStephan Aßmus converter = write_gray1_to_rgb24; 9289949213aSStephan Aßmus } else { 9299949213aSStephan Aßmus out_color_components = 1; 9309949213aSStephan Aßmus out_color_space = JAS_IMAGE_CS_GRAY; 9319949213aSStephan Aßmus converter = write_gray1_to_gray; 9329949213aSStephan Aßmus } 9339949213aSStephan Aßmus break; 934117da2d7SAxel Dörfler 9359949213aSStephan Aßmus case B_CMAP8: 9369949213aSStephan Aßmus converter = write_cmap8_to_rgb24; 9379949213aSStephan Aßmus break; 938117da2d7SAxel Dörfler 9399949213aSStephan Aßmus case B_GRAY8: 9409949213aSStephan Aßmus out_color_components = 1; 9419949213aSStephan Aßmus out_color_space = JAS_IMAGE_CS_GRAY; 9429949213aSStephan Aßmus converter = write_gray; 9439949213aSStephan Aßmus break; 944117da2d7SAxel Dörfler 9459949213aSStephan Aßmus case B_RGB15: 9469949213aSStephan Aßmus case B_RGBA15: 9479949213aSStephan Aßmus converter = write_rgb15_to_rgb24; 9489949213aSStephan Aßmus break; 949117da2d7SAxel Dörfler 9509949213aSStephan Aßmus case B_RGB15_BIG: 9519949213aSStephan Aßmus case B_RGBA15_BIG: 9529949213aSStephan Aßmus converter = write_rgb15b_to_rgb24; 9539949213aSStephan Aßmus break; 954117da2d7SAxel Dörfler 9559949213aSStephan Aßmus case B_RGB16: 9569949213aSStephan Aßmus converter = write_rgb16_to_rgb24; 9579949213aSStephan Aßmus break; 958117da2d7SAxel Dörfler 9599949213aSStephan Aßmus case B_RGB16_BIG: 9609949213aSStephan Aßmus converter = write_rgb16b_to_rgb24; 9619949213aSStephan Aßmus break; 962117da2d7SAxel Dörfler 9639949213aSStephan Aßmus case B_RGB24: 9649949213aSStephan Aßmus converter = write_rgb24; 9659949213aSStephan Aßmus break; 966117da2d7SAxel Dörfler 9679949213aSStephan Aßmus case B_RGB24_BIG: 9689949213aSStephan Aßmus converter = write_rgb24b; 9699949213aSStephan Aßmus break; 970117da2d7SAxel Dörfler 9719949213aSStephan Aßmus case B_RGB32: 9729949213aSStephan Aßmus converter = write_rgb32_to_rgb24; 9739949213aSStephan Aßmus break; 974117da2d7SAxel Dörfler 9759949213aSStephan Aßmus case B_RGB32_BIG: 9769949213aSStephan Aßmus converter = write_rgb32b_to_rgb24; 9779949213aSStephan Aßmus break; 978117da2d7SAxel Dörfler 9799949213aSStephan Aßmus case B_RGBA32: 9809949213aSStephan Aßmus /* 9819949213aSStephan Aßmus // In theory it should be possible to write 4 color components 9829949213aSStephan Aßmus // to jp2, so it should be possible to have transparency. 9839949213aSStephan Aßmus // Unfortunetly libjasper does not agree with that 9849949213aSStephan Aßmus // For now i don't know how to modify it :( 9859949213aSStephan Aßmus 9869949213aSStephan Aßmus out_color_components = 4; 9879949213aSStephan Aßmus converter = write_rgba32; 9889949213aSStephan Aßmus */ 9899949213aSStephan Aßmus converter = write_rgb32_to_rgb24; 9909949213aSStephan Aßmus break; 991117da2d7SAxel Dörfler 9929949213aSStephan Aßmus case B_RGBA32_BIG: 9939949213aSStephan Aßmus /* 9949949213aSStephan Aßmus // In theory it should be possible to write 4 color components 9959949213aSStephan Aßmus // to jp2, so it should be possible to have transparency. 9969949213aSStephan Aßmus // Unfortunetly libjasper does not agree with that 9979949213aSStephan Aßmus // For now i don't know how to modify it :( 9989949213aSStephan Aßmus 9999949213aSStephan Aßmus out_color_components = 4; 10009949213aSStephan Aßmus converter = write_rgba32b; 10019949213aSStephan Aßmus */ 10029949213aSStephan Aßmus converter = write_rgb32b_to_rgb24; 10039949213aSStephan Aßmus break; 1004117da2d7SAxel Dörfler 10059949213aSStephan Aßmus default: 1006*c44966dfSJérôme Duval fprintf(stderr, B_TRANSLATE("Unknown color space.\n")); 10079949213aSStephan Aßmus return B_ERROR; 10089949213aSStephan Aßmus } 10099949213aSStephan Aßmus 10109949213aSStephan Aßmus jas_image_t* image; 10119949213aSStephan Aßmus jas_stream_t* outs; 10129949213aSStephan Aßmus jas_matrix_t* pixels[4]; 10139949213aSStephan Aßmus jas_image_cmptparm_t component_info[4]; 10149949213aSStephan Aßmus 10159949213aSStephan Aßmus if (jas_init()) 10169949213aSStephan Aßmus return B_ERROR; 10179949213aSStephan Aßmus 10189949213aSStephan Aßmus if (!(outs = jas_stream_positionIOopen(out))) 10199949213aSStephan Aßmus return B_ERROR; 10209949213aSStephan Aßmus 10219949213aSStephan Aßmus int32 i = 0; 1022117da2d7SAxel Dörfler for (i = 0; i < (long)out_color_components; i++) { 10239949213aSStephan Aßmus (void) memset(component_info + i, 0, sizeof(jas_image_cmptparm_t)); 10249949213aSStephan Aßmus component_info[i].hstep = 1; 10259949213aSStephan Aßmus component_info[i].vstep = 1; 10269949213aSStephan Aßmus component_info[i].width = (unsigned int)width; 10279949213aSStephan Aßmus component_info[i].height = (unsigned int)height; 10289949213aSStephan Aßmus component_info[i].prec = (unsigned int)8; 10299949213aSStephan Aßmus } 10309949213aSStephan Aßmus 103113eaf8faSStephan Aßmus image = jas_image_create((short)out_color_components, component_info, 103213eaf8faSStephan Aßmus out_color_space); 10339949213aSStephan Aßmus if (image == (jas_image_t *)NULL) 10349949213aSStephan Aßmus return Error(outs, NULL, NULL, 0, NULL, B_ERROR); 10359949213aSStephan Aßmus 10369949213aSStephan Aßmus jpr_uchar_t *in_scanline = (jpr_uchar_t*) malloc(in_row_bytes); 1037117da2d7SAxel Dörfler if (in_scanline == NULL) 1038117da2d7SAxel Dörfler return Error(outs, image, NULL, 0, NULL, B_ERROR); 10399949213aSStephan Aßmus 1040117da2d7SAxel Dörfler for (i = 0; i < (long)out_color_components; i++) { 10419949213aSStephan Aßmus pixels[i] = jas_matrix_create(1, (unsigned int)width); 10429949213aSStephan Aßmus if (pixels[i] == (jas_matrix_t *)NULL) 10439949213aSStephan Aßmus return Error(outs, image, pixels, i+1, in_scanline, B_ERROR); 10449949213aSStephan Aßmus } 10459949213aSStephan Aßmus 10469949213aSStephan Aßmus int32 y = 0; 1047117da2d7SAxel Dörfler for (y = 0; y < (long)height; y++) { 10489949213aSStephan Aßmus err = in->Read(in_scanline, in_row_bytes); 104913eaf8faSStephan Aßmus if (err < in_row_bytes) { 105094a204f0SStephan Aßmus return (err < B_OK) ? Error(outs, image, pixels, 105194a204f0SStephan Aßmus out_color_components, in_scanline, err) 105213eaf8faSStephan Aßmus : Error(outs, image, pixels, out_color_components, in_scanline, 105313eaf8faSStephan Aßmus B_ERROR); 105413eaf8faSStephan Aßmus } 10559949213aSStephan Aßmus 10569949213aSStephan Aßmus converter(pixels, in_scanline, width); 10579949213aSStephan Aßmus 105813eaf8faSStephan Aßmus for (i = 0; i < (long)out_color_components; i++) { 105913eaf8faSStephan Aßmus (void)jas_image_writecmpt(image, (short)i, 0, (unsigned int)y, 106013eaf8faSStephan Aßmus (unsigned int)width, 1, pixels[i]); 106113eaf8faSStephan Aßmus } 10629949213aSStephan Aßmus } 10639949213aSStephan Aßmus 10649949213aSStephan Aßmus char opts[16]; 106594a204f0SStephan Aßmus sprintf(opts, "rate=%1f", 106694a204f0SStephan Aßmus (float)fSettings->SetGetInt32(JP2_SET_QUALITY) / 100.0); 106794a204f0SStephan Aßmus 106894a204f0SStephan Aßmus if (jas_image_encode(image, outs, jas_image_strtofmt( 106994a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_JPC) ? 107013eaf8faSStephan Aßmus (char*)"jpc" : (char*)"jp2"), opts)) { 107194a204f0SStephan Aßmus return Error(outs, image, pixels, 107294a204f0SStephan Aßmus out_color_components, in_scanline, err); 107313eaf8faSStephan Aßmus } 10749949213aSStephan Aßmus 10759949213aSStephan Aßmus free(in_scanline); 10769949213aSStephan Aßmus 10779949213aSStephan Aßmus for (i = 0; i < (long)out_color_components; i++) 10789949213aSStephan Aßmus jas_matrix_destroy(pixels[i]); 1079117da2d7SAxel Dörfler 10809949213aSStephan Aßmus jas_stream_close(outs); 10819949213aSStephan Aßmus jas_image_destroy(image); 10829949213aSStephan Aßmus jas_image_clearfmts(); 10839949213aSStephan Aßmus 10849949213aSStephan Aßmus return B_OK; 10859949213aSStephan Aßmus } 10869949213aSStephan Aßmus 1087117da2d7SAxel Dörfler 1088117da2d7SAxel Dörfler //! Decode the native format 10899949213aSStephan Aßmus status_t 109094a204f0SStephan Aßmus JP2Translator::Decompress(BPositionIO* in, BPositionIO* out) 10919949213aSStephan Aßmus { 109294a204f0SStephan Aßmus using namespace conversion; 10939949213aSStephan Aßmus 10949949213aSStephan Aßmus jas_image_t* image; 10959949213aSStephan Aßmus jas_stream_t* ins; 10969949213aSStephan Aßmus jas_matrix_t* pixels[4]; 10979949213aSStephan Aßmus 10989949213aSStephan Aßmus if (jas_init()) 10999949213aSStephan Aßmus return B_ERROR; 11009949213aSStephan Aßmus 11019949213aSStephan Aßmus if (!(ins = jas_stream_positionIOopen(in))) 11029949213aSStephan Aßmus return B_ERROR; 11039949213aSStephan Aßmus 11049949213aSStephan Aßmus if (!(image = jas_image_decode(ins, -1, 0))) 11059949213aSStephan Aßmus return Error(ins, NULL, NULL, 0, NULL, B_ERROR); 11069949213aSStephan Aßmus 11079949213aSStephan Aßmus // Default color info 11089949213aSStephan Aßmus color_space out_color_space; 11099949213aSStephan Aßmus int out_color_components; 11109949213aSStephan Aßmus int in_color_components = jas_image_numcmpts(image); 11119949213aSStephan Aßmus 11129949213aSStephan Aßmus // Function pointer to read function 11139949213aSStephan Aßmus // It MUST point to proper function 111413eaf8faSStephan Aßmus void (*converter)(jas_matrix_t** pixels, jpr_uchar_t* outscanline, 111513eaf8faSStephan Aßmus int width) = NULL; 11169949213aSStephan Aßmus 1117117da2d7SAxel Dörfler switch (jas_image_colorspace(image)) { 11189949213aSStephan Aßmus case JAS_IMAGE_CS_RGB: 11199949213aSStephan Aßmus out_color_components = 4; 11209949213aSStephan Aßmus if (in_color_components == 3) { 11219949213aSStephan Aßmus out_color_space = B_RGB32; 11229949213aSStephan Aßmus converter = read_rgb24_to_rgb32; 11239949213aSStephan Aßmus } else if (in_color_components == 4) { 11249949213aSStephan Aßmus out_color_space = B_RGBA32; 11259949213aSStephan Aßmus converter = read_rgba32; 11269949213aSStephan Aßmus } else { 1127*c44966dfSJérôme Duval fprintf(stderr, B_TRANSLATE("Other than RGB with 3 or 4 color " 1128*c44966dfSJérôme Duval "components not implemented.\n")); 11299949213aSStephan Aßmus return Error(ins, image, NULL, 0, NULL, B_ERROR); 11309949213aSStephan Aßmus } 11319949213aSStephan Aßmus break; 11329949213aSStephan Aßmus case JAS_IMAGE_CS_GRAY: 113394a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) { 11349949213aSStephan Aßmus out_color_space = B_RGB32; 11359949213aSStephan Aßmus out_color_components = 4; 11369949213aSStephan Aßmus converter = read_gray_to_rgb32; 11379949213aSStephan Aßmus } else { 11389949213aSStephan Aßmus out_color_space = B_GRAY8; 11399949213aSStephan Aßmus out_color_components = 1; 11409949213aSStephan Aßmus converter = read_gray; 11419949213aSStephan Aßmus } 11429949213aSStephan Aßmus break; 11439949213aSStephan Aßmus case JAS_IMAGE_CS_YCBCR: 1144*c44966dfSJérôme Duval fprintf(stderr, B_TRANSLATE("Color space YCBCR not implemented " 1145*c44966dfSJérôme Duval "yet.\n")); 11469949213aSStephan Aßmus return Error(ins, image, NULL, 0, NULL, B_ERROR); 11479949213aSStephan Aßmus break; 11489949213aSStephan Aßmus case JAS_IMAGE_CS_UNKNOWN: 11499949213aSStephan Aßmus default: 1150*c44966dfSJérôme Duval fprintf(stderr, B_TRANSLATE("Color space unknown. \n")); 11519949213aSStephan Aßmus return Error(ins, image, NULL, 0, NULL, B_ERROR); 11529949213aSStephan Aßmus break; 11539949213aSStephan Aßmus } 11549949213aSStephan Aßmus 11559949213aSStephan Aßmus float width = (float)jas_image_width(image); 11569949213aSStephan Aßmus float height = (float)jas_image_height(image); 11579949213aSStephan Aßmus 11589949213aSStephan Aßmus // Bytes count in one line of image (scanline) 11599949213aSStephan Aßmus int64 out_row_bytes = (int32)width * out_color_components; 11609949213aSStephan Aßmus // NOTE: things will go wrong if "out_row_bytes" wouldn't fit into 32 bits 11619949213aSStephan Aßmus 11629949213aSStephan Aßmus // !!! Initialize this bounds rect to the size of your image 11639949213aSStephan Aßmus BRect bounds(0, 0, width - 1, height - 1); 11649949213aSStephan Aßmus 116594a204f0SStephan Aßmus 11669949213aSStephan Aßmus // Fill out the B_TRANSLATOR_BITMAP's header 11679949213aSStephan Aßmus TranslatorBitmap header; 11689949213aSStephan Aßmus header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP); 11699949213aSStephan Aßmus header.bounds.left = B_HOST_TO_BENDIAN_FLOAT(bounds.left); 11709949213aSStephan Aßmus header.bounds.top = B_HOST_TO_BENDIAN_FLOAT(bounds.top); 11719949213aSStephan Aßmus header.bounds.right = B_HOST_TO_BENDIAN_FLOAT(bounds.right); 11729949213aSStephan Aßmus header.bounds.bottom = B_HOST_TO_BENDIAN_FLOAT(bounds.bottom); 11739949213aSStephan Aßmus header.colors = (color_space)B_HOST_TO_BENDIAN_INT32(out_color_space); 11749949213aSStephan Aßmus header.rowBytes = B_HOST_TO_BENDIAN_INT32(out_row_bytes); 11759949213aSStephan Aßmus header.dataSize = B_HOST_TO_BENDIAN_INT32((int32)(out_row_bytes * height)); 11769949213aSStephan Aßmus 11779949213aSStephan Aßmus // Write out the header 11789949213aSStephan Aßmus status_t err = out->Write(&header, sizeof(TranslatorBitmap)); 1179117da2d7SAxel Dörfler if (err < B_OK) 1180117da2d7SAxel Dörfler return Error(ins, image, NULL, 0, NULL, err); 1181117da2d7SAxel Dörfler if (err < (int)sizeof(TranslatorBitmap)) 1182117da2d7SAxel Dörfler return Error(ins, image, NULL, 0, NULL, B_ERROR); 11839949213aSStephan Aßmus 11849949213aSStephan Aßmus jpr_uchar_t *out_scanline = (jpr_uchar_t*) malloc(out_row_bytes); 1185117da2d7SAxel Dörfler if (out_scanline == NULL) 1186117da2d7SAxel Dörfler return Error(ins, image, NULL, 0, NULL, B_ERROR); 11879949213aSStephan Aßmus 11889949213aSStephan Aßmus int32 i = 0; 1189117da2d7SAxel Dörfler for (i = 0; i < (long)in_color_components; i++) { 11909949213aSStephan Aßmus pixels[i] = jas_matrix_create(1, (unsigned int)width); 11919949213aSStephan Aßmus if (pixels[i] == (jas_matrix_t *)NULL) 11929949213aSStephan Aßmus return Error(ins, image, pixels, i + 1, out_scanline, B_ERROR); 11939949213aSStephan Aßmus } 11949949213aSStephan Aßmus 11959949213aSStephan Aßmus int32 y = 0; 1196117da2d7SAxel Dörfler for (y = 0; y < (long)height; y++) { 119713eaf8faSStephan Aßmus for (i = 0; i < (long)in_color_components; i++) { 119813eaf8faSStephan Aßmus (void)jas_image_readcmpt(image, (short)i, 0, (unsigned int)y, 119913eaf8faSStephan Aßmus (unsigned int)width, 1, pixels[i]); 120013eaf8faSStephan Aßmus } 12019949213aSStephan Aßmus 12029949213aSStephan Aßmus converter(pixels, out_scanline, (int32)width); 12039949213aSStephan Aßmus 12049949213aSStephan Aßmus err = out->Write(out_scanline, out_row_bytes); 120513eaf8faSStephan Aßmus if (err < out_row_bytes) { 120694a204f0SStephan Aßmus return (err < B_OK) ? Error(ins, image, pixels, in_color_components, 120794a204f0SStephan Aßmus out_scanline, err) 120813eaf8faSStephan Aßmus : Error(ins, image, pixels, in_color_components, out_scanline, 120913eaf8faSStephan Aßmus B_ERROR); 121013eaf8faSStephan Aßmus } 12119949213aSStephan Aßmus } 12129949213aSStephan Aßmus 12139949213aSStephan Aßmus free(out_scanline); 12149949213aSStephan Aßmus 12159949213aSStephan Aßmus for (i = 0; i < (long)in_color_components; i++) 12169949213aSStephan Aßmus jas_matrix_destroy(pixels[i]); 1217117da2d7SAxel Dörfler 12189949213aSStephan Aßmus jas_stream_close(ins); 12199949213aSStephan Aßmus jas_image_destroy(image); 12209949213aSStephan Aßmus jas_image_clearfmts(); 12219949213aSStephan Aßmus 12229949213aSStephan Aßmus return B_OK; 12239949213aSStephan Aßmus } 12249949213aSStephan Aßmus 1225117da2d7SAxel Dörfler 122694a204f0SStephan Aßmus /*! searches in both inputFormats & outputFormats */ 122794a204f0SStephan Aßmus status_t 122894a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info, 122994a204f0SStephan Aßmus uint32 formatType, translator_id id) 123094a204f0SStephan Aßmus { 123194a204f0SStephan Aßmus int32 formatCount; 123294a204f0SStephan Aßmus const translation_format* formats = OutputFormats(&formatCount); 123394a204f0SStephan Aßmus 123494a204f0SStephan Aßmus for (int i = 0; i <= 1; formats = InputFormats(&formatCount), i++) { 123594a204f0SStephan Aßmus if (PopulateInfoFromFormat(info, formatType, 123694a204f0SStephan Aßmus formats, formatCount) == B_OK) { 123794a204f0SStephan Aßmus info->translator = id; 123894a204f0SStephan Aßmus return B_OK; 123994a204f0SStephan Aßmus } 124094a204f0SStephan Aßmus } 124194a204f0SStephan Aßmus 124294a204f0SStephan Aßmus return B_ERROR; 124394a204f0SStephan Aßmus } 124494a204f0SStephan Aßmus 124594a204f0SStephan Aßmus 124694a204f0SStephan Aßmus status_t 124794a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info, 124894a204f0SStephan Aßmus uint32 formatType, const translation_format* formats, int32 formatCount) 124994a204f0SStephan Aßmus { 125094a204f0SStephan Aßmus for (int i = 0; i < formatCount; i++) { 125194a204f0SStephan Aßmus if (formats[i].type == formatType) { 125294a204f0SStephan Aßmus info->type = formatType; 125394a204f0SStephan Aßmus info->group = formats[i].group; 125494a204f0SStephan Aßmus info->quality = formats[i].quality; 125594a204f0SStephan Aßmus info->capability = formats[i].capability; 1256*c44966dfSJérôme Duval if (strncmp(formats[i].name, 1257*c44966dfSJérôme Duval "Be Bitmap Format (JPEG2000Translator)", 1258*c44966dfSJérôme Duval sizeof("Be Bitmap Format (JPEG2000Translator)")) == 0) 1259*c44966dfSJérôme Duval strncpy(info->name, 1260*c44966dfSJérôme Duval B_TRANSLATE("Be Bitmap Format (JPEG2000Translator)"), 1261*c44966dfSJérôme Duval sizeof(info->name)); 1262*c44966dfSJérôme Duval else 1263*c44966dfSJérôme Duval strncpy(info->name, formats[i].name, sizeof(info->name)); 1264*c44966dfSJérôme Duval strncpy(info->MIME, formats[i].MIME, sizeof(info->MIME)); 126594a204f0SStephan Aßmus return B_OK; 126694a204f0SStephan Aßmus } 126794a204f0SStephan Aßmus } 126894a204f0SStephan Aßmus 126994a204f0SStephan Aßmus return B_ERROR; 127094a204f0SStephan Aßmus } 127194a204f0SStephan Aßmus 127294a204f0SStephan Aßmus 1273117da2d7SAxel Dörfler /*! 1274117da2d7SAxel Dörfler Frees jpeg alocated memory 1275117da2d7SAxel Dörfler Returns given error (B_ERROR by default) 1276117da2d7SAxel Dörfler */ 12779949213aSStephan Aßmus status_t 127813eaf8faSStephan Aßmus Error(jas_stream_t* stream, jas_image_t* image, jas_matrix_t** pixels, 127913eaf8faSStephan Aßmus int32 pixels_count, jpr_uchar_t* scanline, status_t error) 12809949213aSStephan Aßmus { 1281117da2d7SAxel Dörfler if (pixels) { 12829949213aSStephan Aßmus int32 i; 1283117da2d7SAxel Dörfler for (i = 0; i < (long)pixels_count; i++) { 12849949213aSStephan Aßmus if (pixels[i] != NULL) 12859949213aSStephan Aßmus jas_matrix_destroy(pixels[i]); 12869949213aSStephan Aßmus } 1287117da2d7SAxel Dörfler } 12889949213aSStephan Aßmus if (stream) 12899949213aSStephan Aßmus jas_stream_close(stream); 12909949213aSStephan Aßmus if (image) 12919949213aSStephan Aßmus jas_image_destroy(image); 1292117da2d7SAxel Dörfler 12939949213aSStephan Aßmus jas_image_clearfmts(); 12949949213aSStephan Aßmus free(scanline); 12959949213aSStephan Aßmus 12969949213aSStephan Aßmus return error; 12979949213aSStephan Aßmus } 1298117da2d7SAxel Dörfler 1299117da2d7SAxel Dörfler 1300117da2d7SAxel Dörfler // #pragma mark - 1301117da2d7SAxel Dörfler 130294a204f0SStephan Aßmus BTranslator* 130394a204f0SStephan Aßmus make_nth_translator(int32 n, image_id you, uint32 flags, ...) 130494a204f0SStephan Aßmus { 130594a204f0SStephan Aßmus if (!n) 130694a204f0SStephan Aßmus return new JP2Translator(); 130794a204f0SStephan Aßmus 130894a204f0SStephan Aßmus return NULL; 130994a204f0SStephan Aßmus } 131094a204f0SStephan Aßmus 1311117da2d7SAxel Dörfler 1312117da2d7SAxel Dörfler int 1313117da2d7SAxel Dörfler main() 1314117da2d7SAxel Dörfler { 1315117da2d7SAxel Dörfler BApplication app("application/x-vnd.Haiku-JPEG2000Translator"); 131694a204f0SStephan Aßmus JP2Translator* translator = new JP2Translator(); 1317*c44966dfSJérôme Duval if (LaunchTranslatorWindow(translator, B_TRANSLATE("JPEG2000 images") 1318*c44966dfSJérôme Duval /*sTranslatorName*/) == B_OK) 1319117da2d7SAxel Dörfler app.Run(); 132094a204f0SStephan Aßmus 1321117da2d7SAxel Dörfler return 0; 1322117da2d7SAxel Dörfler } 1323117da2d7SAxel Dörfler 1324