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 3870d59669SSiarzhuk Zharski #include <syslog.h> 3970d59669SSiarzhuk Zharski 40*7d48219bSHannah Boneß #include <LayoutBuilder.h> 41117da2d7SAxel Dörfler #include <TabView.h> 4294a204f0SStephan Aßmus #include <TextView.h> 43117da2d7SAxel Dörfler 449949213aSStephan Aßmus 45546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 46546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "JPEG2000Translator" 47c44966dfSJérôme Duval 489949213aSStephan Aßmus // Set these accordingly 499949213aSStephan Aßmus #define JP2_ACRONYM "JP2" 509949213aSStephan Aßmus #define JP2_FORMAT 'JP2 ' 519949213aSStephan Aßmus #define JP2_MIME_STRING "image/jp2" 529949213aSStephan Aßmus #define JP2_DESCRIPTION "JPEG2000 image" 539949213aSStephan Aßmus 549949213aSStephan Aßmus // The translation kit's native file type 559949213aSStephan Aßmus #define B_TRANSLATOR_BITMAP_MIME_STRING "image/x-be-bitmap" 56c095606eSRyan Leavengood #define B_TRANSLATOR_BITMAP_DESCRIPTION "Be Bitmap Format (JPEG2000Translator)" 579949213aSStephan Aßmus 582e49ff35SSiarzhuk Zharski static int32 sTranslatorVersion = B_TRANSLATION_MAKE_VERSION(1, 0, 0); 592e49ff35SSiarzhuk Zharski 601da233a7SSiarzhuk Zharski static const char* sTranslatorName = B_TRANSLATE("JPEG2000 images"); 611da233a7SSiarzhuk Zharski static const char* sTranslatorInfo = B_TRANSLATE("©2002-2003, Shard\n" 62117da2d7SAxel Dörfler "©2005-2006, Haiku\n" 63b0bc48fbSAxel Dörfler "\n" 64b0bc48fbSAxel Dörfler "Based on JasPer library:\n" 65b0bc48fbSAxel Dörfler "© 1999-2000, Image Power, Inc. and\n" 66b0bc48fbSAxel Dörfler "the University of British Columbia, Canada.\n" 67b0bc48fbSAxel Dörfler "© 2001-2003 Michael David Adams.\n" 682e49ff35SSiarzhuk Zharski "\thttp://www.ece.uvic.ca/~mdadams/jasper/\n" 69b0bc48fbSAxel Dörfler "\n" 70b0bc48fbSAxel Dörfler "ImageMagick's jp2 codec was used as \"tutorial\".\n" 712e49ff35SSiarzhuk Zharski "\thttp://www.imagemagick.org/\n"); 729949213aSStephan Aßmus 73bf243977SPhilippe Houdoin static const translation_format sInputFormats[] = { 749949213aSStephan Aßmus { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5, 759949213aSStephan Aßmus JP2_MIME_STRING, JP2_DESCRIPTION }, 769949213aSStephan Aßmus { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5, 779949213aSStephan Aßmus B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION }, 789949213aSStephan Aßmus }; 799949213aSStephan Aßmus 80bf243977SPhilippe Houdoin static const translation_format sOutputFormats[] = { 819949213aSStephan Aßmus { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5, 829949213aSStephan Aßmus JP2_MIME_STRING, JP2_DESCRIPTION }, 839949213aSStephan Aßmus { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5, 849949213aSStephan Aßmus B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION }, 859949213aSStephan Aßmus }; 869949213aSStephan Aßmus 879949213aSStephan Aßmus 88bf243977SPhilippe Houdoin static const TranSetting sDefaultSettings[] = { 8994a204f0SStephan Aßmus {JP2_SET_QUALITY, TRAN_SETTING_INT32, 25}, 9094a204f0SStephan Aßmus {JP2_SET_JPC, TRAN_SETTING_BOOL, false}, 9194a204f0SStephan Aßmus {JP2_SET_GRAY1_AS_B_RGB24, TRAN_SETTING_BOOL, false}, 9294a204f0SStephan Aßmus {JP2_SET_GRAY8_AS_B_RGB32, TRAN_SETTING_BOOL, true} 9394a204f0SStephan Aßmus }; 94bf243977SPhilippe Houdoin 95bf243977SPhilippe Houdoin const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format); 96bf243977SPhilippe Houdoin const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format); 97bf243977SPhilippe Houdoin const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting); 98117da2d7SAxel Dörfler 99117da2d7SAxel Dörfler 10094a204f0SStephan Aßmus namespace conversion{ 101117da2d7SAxel Dörfler //! Make RGB32 scanline from *pixels[3] 102117da2d7SAxel Dörfler inline void 103117da2d7SAxel Dörfler read_rgb24_to_rgb32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 104117da2d7SAxel Dörfler { 105117da2d7SAxel Dörfler int32 index = 0; 106117da2d7SAxel Dörfler int32 x = 0; 107117da2d7SAxel Dörfler while (x < width) { 108117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[2], x); 109117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[1], x); 110117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[0], x); 111117da2d7SAxel Dörfler scanline[index++] = 255; 112117da2d7SAxel Dörfler x++; 113117da2d7SAxel Dörfler } 114117da2d7SAxel Dörfler } 115117da2d7SAxel Dörfler 116117da2d7SAxel Dörfler 117117da2d7SAxel Dörfler //! Make gray scanline from *pixels[1] 118117da2d7SAxel Dörfler inline void 119117da2d7SAxel Dörfler read_gray_to_rgb32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 120117da2d7SAxel Dörfler { 121117da2d7SAxel Dörfler int32 index = 0; 122117da2d7SAxel Dörfler int32 x = 0; 123117da2d7SAxel Dörfler jpr_uchar_t color = 0; 124117da2d7SAxel Dörfler while (x < width) { 125117da2d7SAxel Dörfler color = (jpr_uchar_t)jas_matrix_getv(pixels[0], x++); 126117da2d7SAxel Dörfler scanline[index++] = color; 127117da2d7SAxel Dörfler scanline[index++] = color; 128117da2d7SAxel Dörfler scanline[index++] = color; 129117da2d7SAxel Dörfler scanline[index++] = 255; 130117da2d7SAxel Dörfler } 131117da2d7SAxel Dörfler } 132117da2d7SAxel Dörfler 133117da2d7SAxel Dörfler 134117da2d7SAxel Dörfler /*! 135117da2d7SAxel Dörfler Make RGBA32 scanline from *pixels[4] 136117da2d7SAxel Dörfler (just read data to scanline) 137117da2d7SAxel Dörfler */ 138117da2d7SAxel Dörfler inline void 139117da2d7SAxel Dörfler read_rgba32(jas_matrix_t** pixels, jpr_uchar_t *scanline, int width) 140117da2d7SAxel Dörfler { 141117da2d7SAxel Dörfler int32 index = 0; 142117da2d7SAxel Dörfler int32 x = 0; 143117da2d7SAxel Dörfler while (x < width) { 144117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[2], x); 145117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[1], x); 146117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[0], x); 147117da2d7SAxel Dörfler scanline[index++] = (jpr_uchar_t)jas_matrix_getv(pixels[3], x); 148117da2d7SAxel Dörfler x++; 149117da2d7SAxel Dörfler } 150117da2d7SAxel Dörfler } 151117da2d7SAxel Dörfler 152117da2d7SAxel Dörfler 153117da2d7SAxel Dörfler /*! 154117da2d7SAxel Dörfler Make gray scanline from *pixels[1] 155117da2d7SAxel Dörfler (just read data to scanline) 156117da2d7SAxel Dörfler */ 157117da2d7SAxel Dörfler inline void 158117da2d7SAxel Dörfler read_gray(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 159117da2d7SAxel Dörfler { 160117da2d7SAxel Dörfler int32 x = 0; 161117da2d7SAxel Dörfler while (x < width) { 162117da2d7SAxel Dörfler scanline[x] = (jpr_uchar_t)jas_matrix_getv(pixels[0], x); 163117da2d7SAxel Dörfler x++; 164117da2d7SAxel Dörfler } 165117da2d7SAxel Dörfler } 166117da2d7SAxel Dörfler 167117da2d7SAxel Dörfler 168117da2d7SAxel Dörfler //! Make *pixels[1] from gray1 scanline 169117da2d7SAxel Dörfler inline void 170117da2d7SAxel Dörfler write_gray1_to_gray(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 171117da2d7SAxel Dörfler { 172117da2d7SAxel Dörfler int32 x = 0; 173117da2d7SAxel Dörfler int32 index = 0; 174117da2d7SAxel Dörfler while (x < (width/8)) { 175117da2d7SAxel Dörfler unsigned char c = scanline[x++]; 176117da2d7SAxel Dörfler for (int b = 128; b; b = b >> 1) { 177117da2d7SAxel Dörfler if (c & b) 178117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index++, 0); 179117da2d7SAxel Dörfler else 180117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index++, 255); 181117da2d7SAxel Dörfler } 182117da2d7SAxel Dörfler } 183117da2d7SAxel Dörfler } 184117da2d7SAxel Dörfler 185117da2d7SAxel Dörfler 186117da2d7SAxel Dörfler //! Make *pixels[3] from gray1 scanline 187117da2d7SAxel Dörfler inline void 188117da2d7SAxel Dörfler write_gray1_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 189117da2d7SAxel Dörfler { 190117da2d7SAxel Dörfler int32 x = 0; 191117da2d7SAxel Dörfler int32 index = 0; 192117da2d7SAxel Dörfler while (x < (width / 8)) { 193117da2d7SAxel Dörfler unsigned char c = scanline[x++]; 194117da2d7SAxel Dörfler for (int b = 128; b; b = b >> 1) { 195117da2d7SAxel Dörfler if (c & b) { 196117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index, 0); 197117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], index, 0); 198117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], index, 0); 199117da2d7SAxel Dörfler } else { 200117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], index, 255); 201117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], index, 255); 202117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], index, 255); 203117da2d7SAxel Dörfler } 204117da2d7SAxel Dörfler index++; 205117da2d7SAxel Dörfler } 206117da2d7SAxel Dörfler } 207117da2d7SAxel Dörfler } 208117da2d7SAxel Dörfler 209117da2d7SAxel Dörfler 210117da2d7SAxel Dörfler //! Make *pixels[3] from cmap8 scanline 211117da2d7SAxel Dörfler inline void 212117da2d7SAxel Dörfler write_cmap8_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 213117da2d7SAxel Dörfler { 214117da2d7SAxel Dörfler const color_map* map = system_colors(); 215117da2d7SAxel Dörfler int32 x = 0; 216117da2d7SAxel Dörfler while (x < width) { 217117da2d7SAxel Dörfler rgb_color color = map->color_list[scanline[x]]; 218117da2d7SAxel Dörfler 219117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, color.red); 220117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, color.green); 221117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, color.blue); 222117da2d7SAxel Dörfler x++; 223117da2d7SAxel Dörfler } 224117da2d7SAxel Dörfler } 225117da2d7SAxel Dörfler 226117da2d7SAxel Dörfler 227117da2d7SAxel Dörfler /*! 228117da2d7SAxel Dörfler Make *pixels[1] from gray scanline 229117da2d7SAxel Dörfler (just write data to pixels) 230117da2d7SAxel Dörfler */ 231117da2d7SAxel Dörfler inline void 232117da2d7SAxel Dörfler write_gray(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 233117da2d7SAxel Dörfler { 234117da2d7SAxel Dörfler int32 x = 0; 235117da2d7SAxel Dörfler while (x < width) { 236117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[x]); 237117da2d7SAxel Dörfler x++; 238117da2d7SAxel Dörfler } 239117da2d7SAxel Dörfler } 240117da2d7SAxel Dörfler 241117da2d7SAxel Dörfler 242117da2d7SAxel Dörfler /*! 243117da2d7SAxel Dörfler Make *pixels[3] from RGB15/RGBA15 scanline 244117da2d7SAxel Dörfler (just write data to pixels) 245117da2d7SAxel Dörfler */ 246117da2d7SAxel Dörfler inline void 247117da2d7SAxel Dörfler write_rgb15_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 248117da2d7SAxel Dörfler { 249117da2d7SAxel Dörfler int32 x = 0; 250117da2d7SAxel Dörfler int32 index = 0; 251117da2d7SAxel Dörfler int16 in_pixel; 252117da2d7SAxel Dörfler while (x < width) { 253117da2d7SAxel Dörfler in_pixel = scanline[index] | (scanline[index+1] << 8); 254117da2d7SAxel Dörfler index += 2; 255117da2d7SAxel Dörfler 25694a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7) 25794a204f0SStephan Aßmus | (((in_pixel & 0x7c00)) >> 12)); 25894a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2) 25994a204f0SStephan Aßmus | (((in_pixel & 0x3e0)) >> 7)); 26094a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 26194a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 262117da2d7SAxel Dörfler x++; 263117da2d7SAxel Dörfler } 264117da2d7SAxel Dörfler } 265117da2d7SAxel Dörfler 266117da2d7SAxel Dörfler 267117da2d7SAxel Dörfler /*! 268117da2d7SAxel Dörfler Make *pixels[3] from RGB15/RGBA15 bigendian scanline 269117da2d7SAxel Dörfler (just write data to pixels) 270117da2d7SAxel Dörfler */ 271117da2d7SAxel Dörfler inline void 272117da2d7SAxel Dörfler write_rgb15b_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 273117da2d7SAxel Dörfler { 274117da2d7SAxel Dörfler int32 x = 0; 275117da2d7SAxel Dörfler int32 index = 0; 276117da2d7SAxel Dörfler int16 in_pixel; 277117da2d7SAxel Dörfler while (x < width) { 278117da2d7SAxel Dörfler in_pixel = scanline[index + 1] | (scanline[index] << 8); 279117da2d7SAxel Dörfler index += 2; 280117da2d7SAxel Dörfler 28194a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7) 28294a204f0SStephan Aßmus | (((in_pixel & 0x7c00)) >> 12)); 28394a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2) 28494a204f0SStephan Aßmus | (((in_pixel & 0x3e0)) >> 7)); 28594a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 28694a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 287117da2d7SAxel Dörfler x++; 288117da2d7SAxel Dörfler } 289117da2d7SAxel Dörfler } 290117da2d7SAxel Dörfler 291117da2d7SAxel Dörfler 292117da2d7SAxel Dörfler /*! 293117da2d7SAxel Dörfler Make *pixels[3] from RGB16/RGBA16 scanline 294117da2d7SAxel Dörfler (just write data to pixels) 295117da2d7SAxel Dörfler */ 296117da2d7SAxel Dörfler inline void 297117da2d7SAxel Dörfler write_rgb16_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 298117da2d7SAxel Dörfler { 299117da2d7SAxel Dörfler int32 x = 0; 300117da2d7SAxel Dörfler int32 index = 0; 301117da2d7SAxel Dörfler int16 in_pixel; 302117da2d7SAxel Dörfler while (x < width) { 303117da2d7SAxel Dörfler in_pixel = scanline[index] | (scanline[index+1] << 8); 304117da2d7SAxel Dörfler index += 2; 305117da2d7SAxel Dörfler 30694a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8) 30794a204f0SStephan Aßmus | (((in_pixel & 0x7c00)) >> 12)); 30894a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3) 30994a204f0SStephan Aßmus | (((in_pixel & 0x7e0)) >> 9)); 31094a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 31194a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 312117da2d7SAxel Dörfler x++; 313117da2d7SAxel Dörfler } 314117da2d7SAxel Dörfler } 315117da2d7SAxel Dörfler 316117da2d7SAxel Dörfler 317117da2d7SAxel Dörfler /*! 318117da2d7SAxel Dörfler Make *pixels[3] from RGB16/RGBA16 bigendian scanline 319117da2d7SAxel Dörfler (just write data to pixels) 320117da2d7SAxel Dörfler */ 321117da2d7SAxel Dörfler inline void 322117da2d7SAxel Dörfler write_rgb16b_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 323117da2d7SAxel Dörfler { 324117da2d7SAxel Dörfler int32 x = 0; 325117da2d7SAxel Dörfler int32 index = 0; 326117da2d7SAxel Dörfler int16 in_pixel; 327117da2d7SAxel Dörfler while (x < width) { 328117da2d7SAxel Dörfler in_pixel = scanline[index + 1] | (scanline[index] << 8); 329117da2d7SAxel Dörfler index += 2; 330117da2d7SAxel Dörfler 33194a204f0SStephan Aßmus jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8) 33294a204f0SStephan Aßmus | (((in_pixel & 0xf800)) >> 13)); 33394a204f0SStephan Aßmus jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3) 33494a204f0SStephan Aßmus | (((in_pixel & 0x7e0)) >> 9)); 33594a204f0SStephan Aßmus jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) 33694a204f0SStephan Aßmus | (((in_pixel & 0x1f)) >> 2)); 337117da2d7SAxel Dörfler x++; 338117da2d7SAxel Dörfler } 339117da2d7SAxel Dörfler } 340117da2d7SAxel Dörfler 341117da2d7SAxel Dörfler 342117da2d7SAxel Dörfler /*! 343117da2d7SAxel Dörfler Make *pixels[3] from RGB24 scanline 344117da2d7SAxel Dörfler (just write data to pixels) 345117da2d7SAxel Dörfler */ 346117da2d7SAxel Dörfler inline void 347117da2d7SAxel Dörfler write_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 348117da2d7SAxel Dörfler { 349117da2d7SAxel Dörfler int32 index = 0; 350117da2d7SAxel Dörfler int32 x = 0; 351117da2d7SAxel Dörfler while (x < width) { 352117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 353117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 354117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 355117da2d7SAxel Dörfler x++; 356117da2d7SAxel Dörfler } 357117da2d7SAxel Dörfler } 358117da2d7SAxel Dörfler 359117da2d7SAxel Dörfler 360117da2d7SAxel Dörfler /*! 361117da2d7SAxel Dörfler Make *pixels[3] from RGB24 bigendian scanline 362117da2d7SAxel Dörfler (just write data to pixels) 363117da2d7SAxel Dörfler */ 364117da2d7SAxel Dörfler inline void 365117da2d7SAxel Dörfler write_rgb24b(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 366117da2d7SAxel Dörfler { 367117da2d7SAxel Dörfler int32 index = 0; 368117da2d7SAxel Dörfler int32 x = 0; 369117da2d7SAxel Dörfler while (x < width) { 370117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 371117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 372117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 373117da2d7SAxel Dörfler x++; 374117da2d7SAxel Dörfler } 375117da2d7SAxel Dörfler } 376117da2d7SAxel Dörfler 377117da2d7SAxel Dörfler 378117da2d7SAxel Dörfler /*! 379117da2d7SAxel Dörfler Make *pixels[3] from RGB32 scanline 380117da2d7SAxel Dörfler (just write data to pixels) 381117da2d7SAxel Dörfler */ 382117da2d7SAxel Dörfler inline void 383117da2d7SAxel Dörfler write_rgb32_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 384117da2d7SAxel Dörfler { 385117da2d7SAxel Dörfler int32 index = 0; 386117da2d7SAxel Dörfler int32 x = 0; 387117da2d7SAxel Dörfler while (x < width) { 388117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 389117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 390117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 391117da2d7SAxel Dörfler index++; 392117da2d7SAxel Dörfler x++; 393117da2d7SAxel Dörfler } 394117da2d7SAxel Dörfler } 395117da2d7SAxel Dörfler 396117da2d7SAxel Dörfler 397117da2d7SAxel Dörfler /*! 398117da2d7SAxel Dörfler Make *pixels[3] from RGB32 bigendian scanline 399117da2d7SAxel Dörfler (just write data to pixels) 400117da2d7SAxel Dörfler */ 401117da2d7SAxel Dörfler inline void 402117da2d7SAxel Dörfler write_rgb32b_to_rgb24(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 403117da2d7SAxel Dörfler { 404117da2d7SAxel Dörfler int32 index = 0; 405117da2d7SAxel Dörfler int32 x = 0; 406117da2d7SAxel Dörfler while (x < width) { 407117da2d7SAxel Dörfler index++; 408117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 409117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 410117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 411117da2d7SAxel Dörfler x++; 412117da2d7SAxel Dörfler } 413117da2d7SAxel Dörfler } 414117da2d7SAxel Dörfler 415117da2d7SAxel Dörfler 416117da2d7SAxel Dörfler /*! 417117da2d7SAxel Dörfler Make *pixels[4] from RGBA32 scanline 418117da2d7SAxel Dörfler (just write data to pixels) 419117da2d7SAxel Dörfler !!! UNTESTED !!! 420117da2d7SAxel Dörfler */ 421117da2d7SAxel Dörfler inline void 422117da2d7SAxel Dörfler write_rgba32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 423117da2d7SAxel Dörfler { 424117da2d7SAxel Dörfler int32 index = 0; 425117da2d7SAxel Dörfler int32 x = 0; 426117da2d7SAxel Dörfler while (x < width) { 427117da2d7SAxel Dörfler jas_matrix_setv(pixels[3], x, scanline[index++]); 428117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 429117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 430117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 431117da2d7SAxel Dörfler x++; 432117da2d7SAxel Dörfler } 433117da2d7SAxel Dörfler } 434117da2d7SAxel Dörfler 435117da2d7SAxel Dörfler 436117da2d7SAxel Dörfler /*! 437117da2d7SAxel Dörfler Make *pixels[4] from RGBA32 bigendian scanline 438117da2d7SAxel Dörfler (just write data to pixels) 439117da2d7SAxel Dörfler !!! UNTESTED !!! 440117da2d7SAxel Dörfler */ 441117da2d7SAxel Dörfler inline void 442117da2d7SAxel Dörfler write_rgba32b(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) 443117da2d7SAxel Dörfler { 444117da2d7SAxel Dörfler int32 index = 0; 445117da2d7SAxel Dörfler int32 x = 0; 446117da2d7SAxel Dörfler while (x < width) 447117da2d7SAxel Dörfler { 448117da2d7SAxel Dörfler jas_matrix_setv(pixels[0], x, scanline[index++]); 449117da2d7SAxel Dörfler jas_matrix_setv(pixels[1], x, scanline[index++]); 450117da2d7SAxel Dörfler jas_matrix_setv(pixels[2], x, scanline[index++]); 451117da2d7SAxel Dörfler jas_matrix_setv(pixels[3], x, scanline[index++]); 452117da2d7SAxel Dörfler x++; 453117da2d7SAxel Dörfler } 454117da2d7SAxel Dörfler } 455117da2d7SAxel Dörfler 456117da2d7SAxel Dörfler 45794a204f0SStephan Aßmus }// end namespace conversion 45894a204f0SStephan Aßmus 45994a204f0SStephan Aßmus 460117da2d7SAxel Dörfler // #pragma mark - jasper I/O 461117da2d7SAxel Dörfler 462117da2d7SAxel Dörfler 463117da2d7SAxel Dörfler static int 464117da2d7SAxel Dörfler Read(jas_stream_obj_t* object, char* buffer, const int length) 4659949213aSStephan Aßmus { 4669949213aSStephan Aßmus return (*(BPositionIO**)object)->Read(buffer, length); 4679949213aSStephan Aßmus } 4689949213aSStephan Aßmus 469117da2d7SAxel Dörfler 470117da2d7SAxel Dörfler static int 471117da2d7SAxel Dörfler Write(jas_stream_obj_t* object, char* buffer, const int length) 4729949213aSStephan Aßmus { 4739949213aSStephan Aßmus return (*(BPositionIO**)object)->Write(buffer, length); 4749949213aSStephan Aßmus } 4759949213aSStephan Aßmus 476117da2d7SAxel Dörfler 477117da2d7SAxel Dörfler static long 478117da2d7SAxel Dörfler Seek(jas_stream_obj_t* object, long offset, int origin) 4799949213aSStephan Aßmus { 4809949213aSStephan Aßmus return (*(BPositionIO**)object)->Seek(offset, origin); 4819949213aSStephan Aßmus } 4829949213aSStephan Aßmus 483117da2d7SAxel Dörfler 484117da2d7SAxel Dörfler static int 485117da2d7SAxel Dörfler Close(jas_stream_obj_t* object) 4869949213aSStephan Aßmus { 487117da2d7SAxel Dörfler return 0; 4889949213aSStephan Aßmus } 4899949213aSStephan Aßmus 490117da2d7SAxel Dörfler 491117da2d7SAxel Dörfler static jas_stream_ops_t positionIOops = { 4929949213aSStephan Aßmus Read, 4939949213aSStephan Aßmus Write, 4949949213aSStephan Aßmus Seek, 4959949213aSStephan Aßmus Close 4969949213aSStephan Aßmus }; 4979949213aSStephan Aßmus 498117da2d7SAxel Dörfler 499117da2d7SAxel Dörfler static jas_stream_t* 500117da2d7SAxel Dörfler jas_stream_positionIOopen(BPositionIO *positionIO) 5019949213aSStephan Aßmus { 5029949213aSStephan Aßmus jas_stream_t* stream; 5039949213aSStephan Aßmus 5049949213aSStephan Aßmus stream = (jas_stream_t *)malloc(sizeof(jas_stream_t)); 5059949213aSStephan Aßmus if (stream == (jas_stream_t *)NULL) 506117da2d7SAxel Dörfler return (jas_stream_t *)NULL; 507117da2d7SAxel Dörfler 508117da2d7SAxel Dörfler memset(stream, 0, sizeof(jas_stream_t)); 509117da2d7SAxel Dörfler stream->rwlimit_ = -1; 5109949213aSStephan Aßmus stream->obj_=(jas_stream_obj_t *)malloc(sizeof(BPositionIO*)); 51113eaf8faSStephan Aßmus if (stream->obj_ == (jas_stream_obj_t *)NULL) { 51213eaf8faSStephan Aßmus free(stream); 513117da2d7SAxel Dörfler return (jas_stream_t *)NULL; 51413eaf8faSStephan Aßmus } 515117da2d7SAxel Dörfler 5169949213aSStephan Aßmus *((BPositionIO**)stream->obj_) = positionIO; 5179949213aSStephan Aßmus stream->ops_ = (&positionIOops); 5189949213aSStephan Aßmus stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; 5199949213aSStephan Aßmus stream->bufbase_ = stream->tinybuf_; 5209949213aSStephan Aßmus stream->bufsize_ = 1; 5219949213aSStephan Aßmus stream->bufstart_ = (&stream->bufbase_[JAS_STREAM_MAXPUTBACK]); 5229949213aSStephan Aßmus stream->ptr_ = stream->bufstart_; 5239949213aSStephan Aßmus stream->bufmode_ |= JAS_STREAM_UNBUF & JAS_STREAM_BUFMODEMASK; 524117da2d7SAxel Dörfler 525117da2d7SAxel Dörfler return stream; 5269949213aSStephan Aßmus } 5279949213aSStephan Aßmus 5289949213aSStephan Aßmus 529117da2d7SAxel Dörfler // #pragma mark - 530117da2d7SAxel Dörfler 531117da2d7SAxel Dörfler 53294a204f0SStephan Aßmus SSlider::SSlider(const char* name, const char* label, 533117da2d7SAxel Dörfler BMessage* message, int32 minValue, int32 maxValue, orientation posture, 53494a204f0SStephan Aßmus thumb_style thumbType, uint32 flags) 53594a204f0SStephan Aßmus : 53694a204f0SStephan Aßmus BSlider(name, label, message, minValue, maxValue, 53794a204f0SStephan Aßmus posture, thumbType, flags) 538117da2d7SAxel Dörfler { 539117da2d7SAxel Dörfler rgb_color barColor = { 0, 0, 229, 255 }; 540117da2d7SAxel Dörfler UseFillColor(true, &barColor); 541117da2d7SAxel Dörfler } 542117da2d7SAxel Dörfler 543117da2d7SAxel Dörfler 544117da2d7SAxel Dörfler //! Update status string - show actual value 5456bda235aSStefano Ceccherini const char* 5469949213aSStephan Aßmus SSlider::UpdateText() const 5479949213aSStephan Aßmus { 548117da2d7SAxel Dörfler snprintf(fStatusLabel, sizeof(fStatusLabel), "%ld", Value()); 549117da2d7SAxel Dörfler return fStatusLabel; 5509949213aSStephan Aßmus } 5519949213aSStephan Aßmus 552117da2d7SAxel Dörfler 553117da2d7SAxel Dörfler // #pragma mark - 5549949213aSStephan Aßmus 555117da2d7SAxel Dörfler 55694a204f0SStephan Aßmus TranslatorReadView::TranslatorReadView(const char* name, 55794a204f0SStephan Aßmus TranslatorSettings* settings) 55894a204f0SStephan Aßmus : 55994a204f0SStephan Aßmus BView(name, 0, new BGroupLayout(B_VERTICAL)), 560117da2d7SAxel Dörfler fSettings(settings) 5619949213aSStephan Aßmus { 5622e49ff35SSiarzhuk Zharski fGrayAsRGB32 = new BCheckBox("grayasrgb32", 5632e49ff35SSiarzhuk Zharski B_TRANSLATE("Read greyscale images as RGB32"), 56494a204f0SStephan Aßmus new BMessage(VIEW_MSG_SET_GRAYASRGB32)); 56594a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) 56694a204f0SStephan Aßmus fGrayAsRGB32->SetValue(B_CONTROL_ON); 5679949213aSStephan Aßmus 56894a204f0SStephan Aßmus float padding = 10.0f; 569*7d48219bSHannah Boneß BLayoutBuilder::Group<>(this, B_VERTICAL) 570*7d48219bSHannah Boneß .SetInsets(padding) 57194a204f0SStephan Aßmus .Add(fGrayAsRGB32) 572*7d48219bSHannah Boneß .AddGlue(); 57394a204f0SStephan Aßmus } 57494a204f0SStephan Aßmus 57594a204f0SStephan Aßmus 57694a204f0SStephan Aßmus TranslatorReadView::~TranslatorReadView() 57794a204f0SStephan Aßmus { 57894a204f0SStephan Aßmus fSettings->Release(); 5799949213aSStephan Aßmus } 5809949213aSStephan Aßmus 581117da2d7SAxel Dörfler 5829949213aSStephan Aßmus void 5839949213aSStephan Aßmus TranslatorReadView::AttachedToWindow() 5849949213aSStephan Aßmus { 585117da2d7SAxel Dörfler fGrayAsRGB32->SetTarget(this); 5869949213aSStephan Aßmus } 5879949213aSStephan Aßmus 588117da2d7SAxel Dörfler 5899949213aSStephan Aßmus void 5909949213aSStephan Aßmus TranslatorReadView::MessageReceived(BMessage* message) 5919949213aSStephan Aßmus { 592117da2d7SAxel Dörfler switch (message->what) { 5939949213aSStephan Aßmus case VIEW_MSG_SET_GRAYASRGB32: 5949949213aSStephan Aßmus { 5959949213aSStephan Aßmus int32 value; 5969949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 59794a204f0SStephan Aßmus bool boolValue = value; 59894a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32, &boolValue); 59994a204f0SStephan Aßmus fSettings->SaveSettings(); 6009949213aSStephan Aßmus } 6019949213aSStephan Aßmus break; 6029949213aSStephan Aßmus } 6039949213aSStephan Aßmus default: 6049949213aSStephan Aßmus BView::MessageReceived(message); 6059949213aSStephan Aßmus break; 6069949213aSStephan Aßmus } 6079949213aSStephan Aßmus } 6089949213aSStephan Aßmus 6099949213aSStephan Aßmus 610117da2d7SAxel Dörfler // #pragma mark - TranslatorWriteView 6119949213aSStephan Aßmus 612117da2d7SAxel Dörfler 61394a204f0SStephan Aßmus TranslatorWriteView::TranslatorWriteView(const char* name, 61494a204f0SStephan Aßmus TranslatorSettings* settings) 61594a204f0SStephan Aßmus : 61694a204f0SStephan Aßmus BView(name, 0, new BGroupLayout(B_VERTICAL)), 617117da2d7SAxel Dörfler fSettings(settings) 6189949213aSStephan Aßmus { 6192e49ff35SSiarzhuk Zharski fQualitySlider = new SSlider("quality", B_TRANSLATE("Output quality"), 62094a204f0SStephan Aßmus new BMessage(VIEW_MSG_SET_QUALITY), 0, 100); 621117da2d7SAxel Dörfler fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM); 622117da2d7SAxel Dörfler fQualitySlider->SetHashMarkCount(10); 623c44966dfSJérôme Duval fQualitySlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High")); 62494a204f0SStephan Aßmus fQualitySlider->SetValue(fSettings->SetGetInt32(JP2_SET_QUALITY)); 6259949213aSStephan Aßmus 6262e49ff35SSiarzhuk Zharski fGrayAsRGB24 = new BCheckBox("gray1asrgb24", 6272e49ff35SSiarzhuk Zharski B_TRANSLATE("Write black-and-white images as RGB24"), 628117da2d7SAxel Dörfler new BMessage(VIEW_MSG_SET_GRAY1ASRGB24)); 62994a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) 63094a204f0SStephan Aßmus fGrayAsRGB24->SetValue(B_CONTROL_ON); 6319949213aSStephan Aßmus 6322e49ff35SSiarzhuk Zharski fCodeStreamOnly = new BCheckBox("codestreamonly", 6332e49ff35SSiarzhuk Zharski B_TRANSLATE("Output only codestream (.jpc)"), 63494a204f0SStephan Aßmus new BMessage(VIEW_MSG_SET_JPC)); 63594a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_JPC)) 63694a204f0SStephan Aßmus fCodeStreamOnly->SetValue(B_CONTROL_ON); 6379949213aSStephan Aßmus 63894a204f0SStephan Aßmus float padding = 10.0f; 639*7d48219bSHannah Boneß BLayoutBuilder::Group<>(this, B_VERTICAL, padding) 640*7d48219bSHannah Boneß .SetInsets(padding) 64194a204f0SStephan Aßmus .Add(fQualitySlider) 64294a204f0SStephan Aßmus .Add(fGrayAsRGB24) 64394a204f0SStephan Aßmus .Add(fCodeStreamOnly) 644*7d48219bSHannah Boneß .AddGlue(); 64594a204f0SStephan Aßmus } 646bdaaeb0cSStefano Ceccherini 6479949213aSStephan Aßmus 64894a204f0SStephan Aßmus TranslatorWriteView::~TranslatorWriteView() 64994a204f0SStephan Aßmus { 65094a204f0SStephan Aßmus fSettings->Release(); 6519949213aSStephan Aßmus } 6529949213aSStephan Aßmus 653117da2d7SAxel Dörfler 6549949213aSStephan Aßmus void 6559949213aSStephan Aßmus TranslatorWriteView::AttachedToWindow() 6569949213aSStephan Aßmus { 657117da2d7SAxel Dörfler fQualitySlider->SetTarget(this); 658117da2d7SAxel Dörfler fGrayAsRGB24->SetTarget(this); 659117da2d7SAxel Dörfler fCodeStreamOnly->SetTarget(this); 6609949213aSStephan Aßmus } 6619949213aSStephan Aßmus 662117da2d7SAxel Dörfler 6639949213aSStephan Aßmus void 6649949213aSStephan Aßmus TranslatorWriteView::MessageReceived(BMessage* message) 6659949213aSStephan Aßmus { 666117da2d7SAxel Dörfler switch (message->what) { 6679949213aSStephan Aßmus case VIEW_MSG_SET_QUALITY: 6689949213aSStephan Aßmus { 6699949213aSStephan Aßmus int32 value; 6709949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 67194a204f0SStephan Aßmus fSettings->SetGetInt32(JP2_SET_QUALITY, &value); 67294a204f0SStephan Aßmus fSettings->SaveSettings(); 6739949213aSStephan Aßmus } 6749949213aSStephan Aßmus break; 6759949213aSStephan Aßmus } 6769949213aSStephan Aßmus case VIEW_MSG_SET_GRAY1ASRGB24: 6779949213aSStephan Aßmus { 6789949213aSStephan Aßmus int32 value; 6799949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 68094a204f0SStephan Aßmus bool boolValue = value; 68194a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24, &boolValue); 68294a204f0SStephan Aßmus fSettings->SaveSettings(); 6839949213aSStephan Aßmus } 6849949213aSStephan Aßmus break; 6859949213aSStephan Aßmus } 6869949213aSStephan Aßmus case VIEW_MSG_SET_JPC: 6879949213aSStephan Aßmus { 6889949213aSStephan Aßmus int32 value; 6899949213aSStephan Aßmus if (message->FindInt32("be:value", &value) == B_OK) { 69094a204f0SStephan Aßmus bool boolValue = value; 69194a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_JPC, &boolValue); 69294a204f0SStephan Aßmus fSettings->SaveSettings(); 6939949213aSStephan Aßmus } 6949949213aSStephan Aßmus break; 6959949213aSStephan Aßmus } 6969949213aSStephan Aßmus default: 6979949213aSStephan Aßmus BView::MessageReceived(message); 6989949213aSStephan Aßmus break; 6999949213aSStephan Aßmus } 7009949213aSStephan Aßmus } 7019949213aSStephan Aßmus 7029949213aSStephan Aßmus 703117da2d7SAxel Dörfler // #pragma mark - 7049949213aSStephan Aßmus 705117da2d7SAxel Dörfler 70694a204f0SStephan Aßmus TranslatorAboutView::TranslatorAboutView(const char* name) 70794a204f0SStephan Aßmus : 70894a204f0SStephan Aßmus BView(name, 0, new BGroupLayout(B_VERTICAL)) 7099949213aSStephan Aßmus { 71094a204f0SStephan Aßmus BAlignment labelAlignment = BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP); 7112e49ff35SSiarzhuk Zharski BStringView* title = new BStringView("Title", sTranslatorName); 7129949213aSStephan Aßmus title->SetFont(be_bold_font); 71394a204f0SStephan Aßmus title->SetExplicitAlignment(labelAlignment); 7149949213aSStephan Aßmus 7159949213aSStephan Aßmus char versionString[16]; 716c44966dfSJérôme Duval sprintf(versionString, "v%d.%d.%d", 717c44966dfSJérôme Duval static_cast<int>(sTranslatorVersion >> 8), 718c44966dfSJérôme Duval static_cast<int>((sTranslatorVersion >> 4) & 0xf), 719c44966dfSJérôme Duval static_cast<int>(sTranslatorVersion & 0xf)); 7209949213aSStephan Aßmus 72194a204f0SStephan Aßmus BStringView* version = new BStringView("Version", versionString); 72294a204f0SStephan Aßmus version->SetExplicitAlignment(labelAlignment); 7239949213aSStephan Aßmus 72494a204f0SStephan Aßmus BTextView* infoView = new BTextView("info"); 7252e49ff35SSiarzhuk Zharski infoView->SetText(sTranslatorInfo); 72694a204f0SStephan Aßmus infoView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 72794a204f0SStephan Aßmus infoView->MakeEditable(false); 7289949213aSStephan Aßmus 72994a204f0SStephan Aßmus float padding = 10.0f; 730*7d48219bSHannah Boneß BLayoutBuilder::Group<>(this, B_VERTICAL, padding) 731*7d48219bSHannah Boneß .SetInsets(padding) 732*7d48219bSHannah Boneß .AddGroup(B_HORIZONTAL, padding) 73394a204f0SStephan Aßmus .Add(title) 73494a204f0SStephan Aßmus .Add(version) 73594a204f0SStephan Aßmus .AddGlue() 736*7d48219bSHannah Boneß .End() 737*7d48219bSHannah Boneß .Add(infoView); 7389949213aSStephan Aßmus } 7399949213aSStephan Aßmus 7409949213aSStephan Aßmus 741117da2d7SAxel Dörfler // #pragma mark - 7429949213aSStephan Aßmus 743117da2d7SAxel Dörfler 74494a204f0SStephan Aßmus TranslatorView::TranslatorView(const char* name, TranslatorSettings* settings) 74594a204f0SStephan Aßmus : 74694a204f0SStephan Aßmus BTabView(name) 7479949213aSStephan Aßmus { 748c44966dfSJérôme Duval AddTab(new TranslatorWriteView(B_TRANSLATE("Write"), 749c44966dfSJérôme Duval settings->Acquire())); 750c44966dfSJérôme Duval AddTab(new TranslatorReadView(B_TRANSLATE("Read"), 751c44966dfSJérôme Duval settings->Acquire())); 752c44966dfSJérôme Duval AddTab(new TranslatorAboutView(B_TRANSLATE("About"))); 7539949213aSStephan Aßmus 75494a204f0SStephan Aßmus settings->Release(); 7559949213aSStephan Aßmus 75694a204f0SStephan Aßmus BFont font; 75794a204f0SStephan Aßmus GetFont(&font); 75894a204f0SStephan Aßmus SetExplicitPreferredSize( 75994a204f0SStephan Aßmus BSize((font.Size() * 380) / 12, (font.Size() * 250) / 12)); 7609949213aSStephan Aßmus } 7619949213aSStephan Aßmus 7629949213aSStephan Aßmus 763117da2d7SAxel Dörfler // #pragma mark - 7649949213aSStephan Aßmus 76594a204f0SStephan Aßmus BView* 76694a204f0SStephan Aßmus JP2Translator::NewConfigView(TranslatorSettings* settings) 7679949213aSStephan Aßmus { 76894a204f0SStephan Aßmus BView* outView = new TranslatorView("TranslatorView", settings); 76994a204f0SStephan Aßmus return outView; 7709949213aSStephan Aßmus } 7719949213aSStephan Aßmus 7729949213aSStephan Aßmus 77394a204f0SStephan Aßmus JP2Translator::JP2Translator() 774bf243977SPhilippe Houdoin : BaseTranslator(sTranslatorName, sTranslatorInfo, sTranslatorVersion, 775bf243977SPhilippe Houdoin sInputFormats, kNumInputFormats, 776bf243977SPhilippe Houdoin sOutputFormats, kNumOutputFormats, 777bf243977SPhilippe Houdoin JP2_SETTINGS_FILE, 778bf243977SPhilippe Houdoin sDefaultSettings, kNumDefaultSettings, 779bf243977SPhilippe Houdoin B_TRANSLATOR_BITMAP, JP2_FORMAT) 7809949213aSStephan Aßmus { 7819949213aSStephan Aßmus } 7829949213aSStephan Aßmus 783117da2d7SAxel Dörfler 784117da2d7SAxel Dörfler //! Determine whether or not we can handle this data 7859949213aSStephan Aßmus status_t 78694a204f0SStephan Aßmus JP2Translator::DerivedIdentify(BPositionIO* inSource, 78794a204f0SStephan Aßmus const translation_format* inFormat, BMessage* ioExtension, 78894a204f0SStephan Aßmus translator_info* outInfo, uint32 outType) 7899949213aSStephan Aßmus { 79013eaf8faSStephan Aßmus if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP) 79113eaf8faSStephan Aßmus && outType != JP2_FORMAT) 7929949213aSStephan Aßmus return B_NO_TRANSLATOR; 7939949213aSStephan Aßmus 79413eaf8faSStephan Aßmus // !!! You might need to make this buffer bigger to test for your 79513eaf8faSStephan Aßmus // native format 7969949213aSStephan Aßmus off_t position = inSource->Position(); 7979949213aSStephan Aßmus uint8 header[sizeof(TranslatorBitmap)]; 7989949213aSStephan Aßmus status_t err = inSource->Read(header, sizeof(TranslatorBitmap)); 7999949213aSStephan Aßmus inSource->Seek(position, SEEK_SET); 800117da2d7SAxel Dörfler if (err < B_OK) 801117da2d7SAxel Dörfler return err; 8029949213aSStephan Aßmus 80313eaf8faSStephan Aßmus if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic) 80413eaf8faSStephan Aßmus == B_TRANSLATOR_BITMAP) { 80594a204f0SStephan Aßmus if (PopulateInfoFromFormat(outInfo, B_TRANSLATOR_BITMAP) != B_OK) 80694a204f0SStephan Aßmus return B_NO_TRANSLATOR; 8079949213aSStephan Aßmus } else { 80813eaf8faSStephan Aßmus if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8) 80913eaf8faSStephan Aßmus | header[7]) == JP2_BOX_JP) // JP2 81013eaf8faSStephan Aßmus || (header[0] == (JPC_MS_SOC >> 8) && header[1] 81113eaf8faSStephan Aßmus == (JPC_MS_SOC & 0xff))) // JPC 8129949213aSStephan Aßmus { 81394a204f0SStephan Aßmus if (PopulateInfoFromFormat(outInfo, JP2_FORMAT) != B_OK) 81494a204f0SStephan Aßmus return B_NO_TRANSLATOR; 8159949213aSStephan Aßmus } else 8169949213aSStephan Aßmus return B_NO_TRANSLATOR; 8179949213aSStephan Aßmus } 8189949213aSStephan Aßmus 8199949213aSStephan Aßmus return B_OK; 8209949213aSStephan Aßmus } 8219949213aSStephan Aßmus 822117da2d7SAxel Dörfler 8239949213aSStephan Aßmus status_t 82494a204f0SStephan Aßmus JP2Translator::DerivedTranslate(BPositionIO* inSource, 82594a204f0SStephan Aßmus const translator_info* inInfo, BMessage* ioExtension, uint32 outType, 82694a204f0SStephan Aßmus BPositionIO* outDestination, int32 baseType) 8279949213aSStephan Aßmus { 8289949213aSStephan Aßmus // If no specific type was requested, convert to the interchange format 829117da2d7SAxel Dörfler if (outType == 0) 830117da2d7SAxel Dörfler outType = B_TRANSLATOR_BITMAP; 8319949213aSStephan Aßmus 8329949213aSStephan Aßmus // What action to take, based on the findings of Identify() 833117da2d7SAxel Dörfler if (outType == inInfo->type) 8349949213aSStephan Aßmus return Copy(inSource, outDestination); 835117da2d7SAxel Dörfler if (inInfo->type == B_TRANSLATOR_BITMAP && outType == JP2_FORMAT) 8369949213aSStephan Aßmus return Compress(inSource, outDestination); 837117da2d7SAxel Dörfler if (inInfo->type == JP2_FORMAT && outType == B_TRANSLATOR_BITMAP) 8389949213aSStephan Aßmus return Decompress(inSource, outDestination); 8399949213aSStephan Aßmus 8409949213aSStephan Aßmus return B_NO_TRANSLATOR; 8419949213aSStephan Aßmus } 8429949213aSStephan Aßmus 843117da2d7SAxel Dörfler 844117da2d7SAxel Dörfler //! The user has requested the same format for input and output, so just copy 8459949213aSStephan Aßmus status_t 84694a204f0SStephan Aßmus JP2Translator::Copy(BPositionIO* in, BPositionIO* out) 8479949213aSStephan Aßmus { 8489949213aSStephan Aßmus int block_size = 65536; 8499949213aSStephan Aßmus void* buffer = malloc(block_size); 8509949213aSStephan Aßmus char temp[1024]; 8519949213aSStephan Aßmus if (buffer == NULL) { 8529949213aSStephan Aßmus buffer = temp; 8539949213aSStephan Aßmus block_size = 1024; 8549949213aSStephan Aßmus } 8559949213aSStephan Aßmus status_t err = B_OK; 8569949213aSStephan Aßmus 8579949213aSStephan Aßmus // Read until end of file or error 8589949213aSStephan Aßmus while (1) { 8599949213aSStephan Aßmus ssize_t to_read = block_size; 8609949213aSStephan Aßmus err = in->Read(buffer, to_read); 8619949213aSStephan Aßmus // Explicit check for EOF 8629949213aSStephan Aßmus if (err == -1) { 863117da2d7SAxel Dörfler if (buffer != temp) 864117da2d7SAxel Dörfler free(buffer); 8659949213aSStephan Aßmus return B_OK; 8669949213aSStephan Aßmus } 8679949213aSStephan Aßmus if (err <= B_OK) break; 8689949213aSStephan Aßmus to_read = err; 8699949213aSStephan Aßmus err = out->Write(buffer, to_read); 8709949213aSStephan Aßmus if (err != to_read) if (err >= 0) err = B_DEVICE_FULL; 8719949213aSStephan Aßmus if (err < B_OK) break; 8729949213aSStephan Aßmus } 8739949213aSStephan Aßmus 874117da2d7SAxel Dörfler if (buffer != temp) 875117da2d7SAxel Dörfler free(buffer); 8769949213aSStephan Aßmus return (err >= 0) ? B_OK : err; 8779949213aSStephan Aßmus } 8789949213aSStephan Aßmus 879117da2d7SAxel Dörfler 880117da2d7SAxel Dörfler //! Encode into the native format 8819949213aSStephan Aßmus status_t 88294a204f0SStephan Aßmus JP2Translator::Compress(BPositionIO* in, BPositionIO* out) 8839949213aSStephan Aßmus { 88494a204f0SStephan Aßmus using namespace conversion; 8859949213aSStephan Aßmus 8869949213aSStephan Aßmus // Read info about bitmap 8879949213aSStephan Aßmus TranslatorBitmap header; 8889949213aSStephan Aßmus status_t err = in->Read(&header, sizeof(TranslatorBitmap)); 889117da2d7SAxel Dörfler if (err < B_OK) 890117da2d7SAxel Dörfler return err; 891117da2d7SAxel Dörfler if (err < (int)sizeof(TranslatorBitmap)) 892117da2d7SAxel Dörfler return B_ERROR; 8939949213aSStephan Aßmus 8949949213aSStephan Aßmus // Grab dimension, color space, and size information from the stream 8959949213aSStephan Aßmus BRect bounds; 8969949213aSStephan Aßmus bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left); 8979949213aSStephan Aßmus bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top); 8989949213aSStephan Aßmus bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right); 8999949213aSStephan Aßmus bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom); 9009949213aSStephan Aßmus 9019949213aSStephan Aßmus int32 in_row_bytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes); 9029949213aSStephan Aßmus 9039949213aSStephan Aßmus int width = bounds.IntegerWidth() + 1; 9049949213aSStephan Aßmus int height = bounds.IntegerHeight() + 1; 9059949213aSStephan Aßmus 9069949213aSStephan Aßmus // Function pointer to write function 9079949213aSStephan Aßmus // It MUST point to proper function 90813eaf8faSStephan Aßmus void (*converter)(jas_matrix_t** pixels, jpr_uchar_t* inscanline, 90913eaf8faSStephan Aßmus int width) = write_rgba32; 9109949213aSStephan Aßmus 9119949213aSStephan Aßmus // Default color info 9129949213aSStephan Aßmus int out_color_space = JAS_IMAGE_CS_RGB; 9139949213aSStephan Aßmus int out_color_components = 3; 9149949213aSStephan Aßmus 915117da2d7SAxel Dörfler switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) { 9169949213aSStephan Aßmus case B_GRAY1: 91794a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) { 9189949213aSStephan Aßmus converter = write_gray1_to_rgb24; 9199949213aSStephan Aßmus } else { 9209949213aSStephan Aßmus out_color_components = 1; 9219949213aSStephan Aßmus out_color_space = JAS_IMAGE_CS_GRAY; 9229949213aSStephan Aßmus converter = write_gray1_to_gray; 9239949213aSStephan Aßmus } 9249949213aSStephan Aßmus break; 925117da2d7SAxel Dörfler 9269949213aSStephan Aßmus case B_CMAP8: 9279949213aSStephan Aßmus converter = write_cmap8_to_rgb24; 9289949213aSStephan Aßmus break; 929117da2d7SAxel Dörfler 9309949213aSStephan Aßmus case B_GRAY8: 9319949213aSStephan Aßmus out_color_components = 1; 9329949213aSStephan Aßmus out_color_space = JAS_IMAGE_CS_GRAY; 9339949213aSStephan Aßmus converter = write_gray; 9349949213aSStephan Aßmus break; 935117da2d7SAxel Dörfler 9369949213aSStephan Aßmus case B_RGB15: 9379949213aSStephan Aßmus case B_RGBA15: 9389949213aSStephan Aßmus converter = write_rgb15_to_rgb24; 9399949213aSStephan Aßmus break; 940117da2d7SAxel Dörfler 9419949213aSStephan Aßmus case B_RGB15_BIG: 9429949213aSStephan Aßmus case B_RGBA15_BIG: 9439949213aSStephan Aßmus converter = write_rgb15b_to_rgb24; 9449949213aSStephan Aßmus break; 945117da2d7SAxel Dörfler 9469949213aSStephan Aßmus case B_RGB16: 9479949213aSStephan Aßmus converter = write_rgb16_to_rgb24; 9489949213aSStephan Aßmus break; 949117da2d7SAxel Dörfler 9509949213aSStephan Aßmus case B_RGB16_BIG: 9519949213aSStephan Aßmus converter = write_rgb16b_to_rgb24; 9529949213aSStephan Aßmus break; 953117da2d7SAxel Dörfler 9549949213aSStephan Aßmus case B_RGB24: 9559949213aSStephan Aßmus converter = write_rgb24; 9569949213aSStephan Aßmus break; 957117da2d7SAxel Dörfler 9589949213aSStephan Aßmus case B_RGB24_BIG: 9599949213aSStephan Aßmus converter = write_rgb24b; 9609949213aSStephan Aßmus break; 961117da2d7SAxel Dörfler 9629949213aSStephan Aßmus case B_RGB32: 9639949213aSStephan Aßmus converter = write_rgb32_to_rgb24; 9649949213aSStephan Aßmus break; 965117da2d7SAxel Dörfler 9669949213aSStephan Aßmus case B_RGB32_BIG: 9679949213aSStephan Aßmus converter = write_rgb32b_to_rgb24; 9689949213aSStephan Aßmus break; 969117da2d7SAxel Dörfler 9709949213aSStephan Aßmus case B_RGBA32: 9719949213aSStephan Aßmus /* 9729949213aSStephan Aßmus // In theory it should be possible to write 4 color components 9739949213aSStephan Aßmus // to jp2, so it should be possible to have transparency. 9749949213aSStephan Aßmus // Unfortunetly libjasper does not agree with that 9759949213aSStephan Aßmus // For now i don't know how to modify it :( 9769949213aSStephan Aßmus 9779949213aSStephan Aßmus out_color_components = 4; 9789949213aSStephan Aßmus converter = write_rgba32; 9799949213aSStephan Aßmus */ 9809949213aSStephan Aßmus converter = write_rgb32_to_rgb24; 9819949213aSStephan Aßmus break; 982117da2d7SAxel Dörfler 9839949213aSStephan Aßmus case B_RGBA32_BIG: 9849949213aSStephan Aßmus /* 9859949213aSStephan Aßmus // In theory it should be possible to write 4 color components 9869949213aSStephan Aßmus // to jp2, so it should be possible to have transparency. 9879949213aSStephan Aßmus // Unfortunetly libjasper does not agree with that 9889949213aSStephan Aßmus // For now i don't know how to modify it :( 9899949213aSStephan Aßmus 9909949213aSStephan Aßmus out_color_components = 4; 9919949213aSStephan Aßmus converter = write_rgba32b; 9929949213aSStephan Aßmus */ 9939949213aSStephan Aßmus converter = write_rgb32b_to_rgb24; 9949949213aSStephan Aßmus break; 995117da2d7SAxel Dörfler 9969949213aSStephan Aßmus default: 99770d59669SSiarzhuk Zharski syslog(LOG_ERR, "Unknown color space.\n"); 9989949213aSStephan Aßmus return B_ERROR; 9999949213aSStephan Aßmus } 10009949213aSStephan Aßmus 10019949213aSStephan Aßmus jas_image_t* image; 10029949213aSStephan Aßmus jas_stream_t* outs; 10039949213aSStephan Aßmus jas_matrix_t* pixels[4]; 10049949213aSStephan Aßmus jas_image_cmptparm_t component_info[4]; 10059949213aSStephan Aßmus 10069949213aSStephan Aßmus if (jas_init()) 10079949213aSStephan Aßmus return B_ERROR; 10089949213aSStephan Aßmus 10099949213aSStephan Aßmus if (!(outs = jas_stream_positionIOopen(out))) 10109949213aSStephan Aßmus return B_ERROR; 10119949213aSStephan Aßmus 10129949213aSStephan Aßmus int32 i = 0; 1013117da2d7SAxel Dörfler for (i = 0; i < (long)out_color_components; i++) { 10149949213aSStephan Aßmus (void) memset(component_info + i, 0, sizeof(jas_image_cmptparm_t)); 10159949213aSStephan Aßmus component_info[i].hstep = 1; 10169949213aSStephan Aßmus component_info[i].vstep = 1; 10179949213aSStephan Aßmus component_info[i].width = (unsigned int)width; 10189949213aSStephan Aßmus component_info[i].height = (unsigned int)height; 10199949213aSStephan Aßmus component_info[i].prec = (unsigned int)8; 10209949213aSStephan Aßmus } 10219949213aSStephan Aßmus 102213eaf8faSStephan Aßmus image = jas_image_create((short)out_color_components, component_info, 102313eaf8faSStephan Aßmus out_color_space); 10249949213aSStephan Aßmus if (image == (jas_image_t *)NULL) 10259949213aSStephan Aßmus return Error(outs, NULL, NULL, 0, NULL, B_ERROR); 10269949213aSStephan Aßmus 10279949213aSStephan Aßmus jpr_uchar_t *in_scanline = (jpr_uchar_t*) malloc(in_row_bytes); 1028117da2d7SAxel Dörfler if (in_scanline == NULL) 1029117da2d7SAxel Dörfler return Error(outs, image, NULL, 0, NULL, B_ERROR); 10309949213aSStephan Aßmus 1031117da2d7SAxel Dörfler for (i = 0; i < (long)out_color_components; i++) { 10329949213aSStephan Aßmus pixels[i] = jas_matrix_create(1, (unsigned int)width); 10339949213aSStephan Aßmus if (pixels[i] == (jas_matrix_t *)NULL) 10349949213aSStephan Aßmus return Error(outs, image, pixels, i+1, in_scanline, B_ERROR); 10359949213aSStephan Aßmus } 10369949213aSStephan Aßmus 10379949213aSStephan Aßmus int32 y = 0; 1038117da2d7SAxel Dörfler for (y = 0; y < (long)height; y++) { 10399949213aSStephan Aßmus err = in->Read(in_scanline, in_row_bytes); 104013eaf8faSStephan Aßmus if (err < in_row_bytes) { 104194a204f0SStephan Aßmus return (err < B_OK) ? Error(outs, image, pixels, 104294a204f0SStephan Aßmus out_color_components, in_scanline, err) 104313eaf8faSStephan Aßmus : Error(outs, image, pixels, out_color_components, in_scanline, 104413eaf8faSStephan Aßmus B_ERROR); 104513eaf8faSStephan Aßmus } 10469949213aSStephan Aßmus 10479949213aSStephan Aßmus converter(pixels, in_scanline, width); 10489949213aSStephan Aßmus 104913eaf8faSStephan Aßmus for (i = 0; i < (long)out_color_components; i++) { 105013eaf8faSStephan Aßmus (void)jas_image_writecmpt(image, (short)i, 0, (unsigned int)y, 105113eaf8faSStephan Aßmus (unsigned int)width, 1, pixels[i]); 105213eaf8faSStephan Aßmus } 10539949213aSStephan Aßmus } 10549949213aSStephan Aßmus 10559949213aSStephan Aßmus char opts[16]; 105694a204f0SStephan Aßmus sprintf(opts, "rate=%1f", 105794a204f0SStephan Aßmus (float)fSettings->SetGetInt32(JP2_SET_QUALITY) / 100.0); 105894a204f0SStephan Aßmus 105994a204f0SStephan Aßmus if (jas_image_encode(image, outs, jas_image_strtofmt( 106094a204f0SStephan Aßmus fSettings->SetGetBool(JP2_SET_JPC) ? 106113eaf8faSStephan Aßmus (char*)"jpc" : (char*)"jp2"), opts)) { 106294a204f0SStephan Aßmus return Error(outs, image, pixels, 106394a204f0SStephan Aßmus out_color_components, in_scanline, err); 106413eaf8faSStephan Aßmus } 10659949213aSStephan Aßmus 10669949213aSStephan Aßmus free(in_scanline); 10679949213aSStephan Aßmus 10689949213aSStephan Aßmus for (i = 0; i < (long)out_color_components; i++) 10699949213aSStephan Aßmus jas_matrix_destroy(pixels[i]); 1070117da2d7SAxel Dörfler 10719949213aSStephan Aßmus jas_stream_close(outs); 10729949213aSStephan Aßmus jas_image_destroy(image); 10739949213aSStephan Aßmus jas_image_clearfmts(); 10749949213aSStephan Aßmus 10759949213aSStephan Aßmus return B_OK; 10769949213aSStephan Aßmus } 10779949213aSStephan Aßmus 1078117da2d7SAxel Dörfler 1079117da2d7SAxel Dörfler //! Decode the native format 10809949213aSStephan Aßmus status_t 108194a204f0SStephan Aßmus JP2Translator::Decompress(BPositionIO* in, BPositionIO* out) 10829949213aSStephan Aßmus { 108394a204f0SStephan Aßmus using namespace conversion; 10849949213aSStephan Aßmus 10859949213aSStephan Aßmus jas_image_t* image; 10869949213aSStephan Aßmus jas_stream_t* ins; 10879949213aSStephan Aßmus jas_matrix_t* pixels[4]; 10889949213aSStephan Aßmus 10899949213aSStephan Aßmus if (jas_init()) 10909949213aSStephan Aßmus return B_ERROR; 10919949213aSStephan Aßmus 10929949213aSStephan Aßmus if (!(ins = jas_stream_positionIOopen(in))) 10939949213aSStephan Aßmus return B_ERROR; 10949949213aSStephan Aßmus 10959949213aSStephan Aßmus if (!(image = jas_image_decode(ins, -1, 0))) 10969949213aSStephan Aßmus return Error(ins, NULL, NULL, 0, NULL, B_ERROR); 10979949213aSStephan Aßmus 10989949213aSStephan Aßmus // Default color info 10999949213aSStephan Aßmus color_space out_color_space; 11009949213aSStephan Aßmus int out_color_components; 11019949213aSStephan Aßmus int in_color_components = jas_image_numcmpts(image); 11029949213aSStephan Aßmus 11039949213aSStephan Aßmus // Function pointer to read function 11049949213aSStephan Aßmus // It MUST point to proper function 110513eaf8faSStephan Aßmus void (*converter)(jas_matrix_t** pixels, jpr_uchar_t* outscanline, 110613eaf8faSStephan Aßmus int width) = NULL; 11079949213aSStephan Aßmus 1108117da2d7SAxel Dörfler switch (jas_image_colorspace(image)) { 11099949213aSStephan Aßmus case JAS_IMAGE_CS_RGB: 11109949213aSStephan Aßmus out_color_components = 4; 11119949213aSStephan Aßmus if (in_color_components == 3) { 11129949213aSStephan Aßmus out_color_space = B_RGB32; 11139949213aSStephan Aßmus converter = read_rgb24_to_rgb32; 11149949213aSStephan Aßmus } else if (in_color_components == 4) { 11159949213aSStephan Aßmus out_color_space = B_RGBA32; 11169949213aSStephan Aßmus converter = read_rgba32; 11179949213aSStephan Aßmus } else { 111870d59669SSiarzhuk Zharski syslog(LOG_ERR, "Other than RGB with 3 or 4 color " 111970d59669SSiarzhuk Zharski "components not implemented.\n"); 11209949213aSStephan Aßmus return Error(ins, image, NULL, 0, NULL, B_ERROR); 11219949213aSStephan Aßmus } 11229949213aSStephan Aßmus break; 11239949213aSStephan Aßmus case JAS_IMAGE_CS_GRAY: 112494a204f0SStephan Aßmus if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) { 11259949213aSStephan Aßmus out_color_space = B_RGB32; 11269949213aSStephan Aßmus out_color_components = 4; 11279949213aSStephan Aßmus converter = read_gray_to_rgb32; 11289949213aSStephan Aßmus } else { 11299949213aSStephan Aßmus out_color_space = B_GRAY8; 11309949213aSStephan Aßmus out_color_components = 1; 11319949213aSStephan Aßmus converter = read_gray; 11329949213aSStephan Aßmus } 11339949213aSStephan Aßmus break; 11349949213aSStephan Aßmus case JAS_IMAGE_CS_YCBCR: 113570d59669SSiarzhuk Zharski syslog(LOG_ERR, "Color space YCBCR not implemented yet.\n"); 11369949213aSStephan Aßmus return Error(ins, image, NULL, 0, NULL, B_ERROR); 11379949213aSStephan Aßmus break; 11389949213aSStephan Aßmus case JAS_IMAGE_CS_UNKNOWN: 11399949213aSStephan Aßmus default: 114070d59669SSiarzhuk Zharski syslog(LOG_ERR, "Color space unknown. \n"); 11419949213aSStephan Aßmus return Error(ins, image, NULL, 0, NULL, B_ERROR); 11429949213aSStephan Aßmus break; 11439949213aSStephan Aßmus } 11449949213aSStephan Aßmus 11459949213aSStephan Aßmus float width = (float)jas_image_width(image); 11469949213aSStephan Aßmus float height = (float)jas_image_height(image); 11479949213aSStephan Aßmus 11489949213aSStephan Aßmus // Bytes count in one line of image (scanline) 11499949213aSStephan Aßmus int64 out_row_bytes = (int32)width * out_color_components; 11509949213aSStephan Aßmus // NOTE: things will go wrong if "out_row_bytes" wouldn't fit into 32 bits 11519949213aSStephan Aßmus 11529949213aSStephan Aßmus // !!! Initialize this bounds rect to the size of your image 11539949213aSStephan Aßmus BRect bounds(0, 0, width - 1, height - 1); 11549949213aSStephan Aßmus 115594a204f0SStephan Aßmus 11569949213aSStephan Aßmus // Fill out the B_TRANSLATOR_BITMAP's header 11579949213aSStephan Aßmus TranslatorBitmap header; 11589949213aSStephan Aßmus header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP); 11599949213aSStephan Aßmus header.bounds.left = B_HOST_TO_BENDIAN_FLOAT(bounds.left); 11609949213aSStephan Aßmus header.bounds.top = B_HOST_TO_BENDIAN_FLOAT(bounds.top); 11619949213aSStephan Aßmus header.bounds.right = B_HOST_TO_BENDIAN_FLOAT(bounds.right); 11629949213aSStephan Aßmus header.bounds.bottom = B_HOST_TO_BENDIAN_FLOAT(bounds.bottom); 11639949213aSStephan Aßmus header.colors = (color_space)B_HOST_TO_BENDIAN_INT32(out_color_space); 11649949213aSStephan Aßmus header.rowBytes = B_HOST_TO_BENDIAN_INT32(out_row_bytes); 11659949213aSStephan Aßmus header.dataSize = B_HOST_TO_BENDIAN_INT32((int32)(out_row_bytes * height)); 11669949213aSStephan Aßmus 11679949213aSStephan Aßmus // Write out the header 11689949213aSStephan Aßmus status_t err = out->Write(&header, sizeof(TranslatorBitmap)); 1169117da2d7SAxel Dörfler if (err < B_OK) 1170117da2d7SAxel Dörfler return Error(ins, image, NULL, 0, NULL, err); 1171117da2d7SAxel Dörfler if (err < (int)sizeof(TranslatorBitmap)) 1172117da2d7SAxel Dörfler return Error(ins, image, NULL, 0, NULL, B_ERROR); 11739949213aSStephan Aßmus 11749949213aSStephan Aßmus jpr_uchar_t *out_scanline = (jpr_uchar_t*) malloc(out_row_bytes); 1175117da2d7SAxel Dörfler if (out_scanline == NULL) 1176117da2d7SAxel Dörfler return Error(ins, image, NULL, 0, NULL, B_ERROR); 11779949213aSStephan Aßmus 11789949213aSStephan Aßmus int32 i = 0; 1179117da2d7SAxel Dörfler for (i = 0; i < (long)in_color_components; i++) { 11809949213aSStephan Aßmus pixels[i] = jas_matrix_create(1, (unsigned int)width); 11819949213aSStephan Aßmus if (pixels[i] == (jas_matrix_t *)NULL) 11829949213aSStephan Aßmus return Error(ins, image, pixels, i + 1, out_scanline, B_ERROR); 11839949213aSStephan Aßmus } 11849949213aSStephan Aßmus 11859949213aSStephan Aßmus int32 y = 0; 1186117da2d7SAxel Dörfler for (y = 0; y < (long)height; y++) { 118713eaf8faSStephan Aßmus for (i = 0; i < (long)in_color_components; i++) { 118813eaf8faSStephan Aßmus (void)jas_image_readcmpt(image, (short)i, 0, (unsigned int)y, 118913eaf8faSStephan Aßmus (unsigned int)width, 1, pixels[i]); 119013eaf8faSStephan Aßmus } 11919949213aSStephan Aßmus 11929949213aSStephan Aßmus converter(pixels, out_scanline, (int32)width); 11939949213aSStephan Aßmus 11949949213aSStephan Aßmus err = out->Write(out_scanline, out_row_bytes); 119513eaf8faSStephan Aßmus if (err < out_row_bytes) { 119694a204f0SStephan Aßmus return (err < B_OK) ? Error(ins, image, pixels, in_color_components, 119794a204f0SStephan Aßmus out_scanline, err) 119813eaf8faSStephan Aßmus : Error(ins, image, pixels, in_color_components, out_scanline, 119913eaf8faSStephan Aßmus B_ERROR); 120013eaf8faSStephan Aßmus } 12019949213aSStephan Aßmus } 12029949213aSStephan Aßmus 12039949213aSStephan Aßmus free(out_scanline); 12049949213aSStephan Aßmus 12059949213aSStephan Aßmus for (i = 0; i < (long)in_color_components; i++) 12069949213aSStephan Aßmus jas_matrix_destroy(pixels[i]); 1207117da2d7SAxel Dörfler 12089949213aSStephan Aßmus jas_stream_close(ins); 12099949213aSStephan Aßmus jas_image_destroy(image); 12109949213aSStephan Aßmus jas_image_clearfmts(); 12119949213aSStephan Aßmus 12129949213aSStephan Aßmus return B_OK; 12139949213aSStephan Aßmus } 12149949213aSStephan Aßmus 1215117da2d7SAxel Dörfler 121694a204f0SStephan Aßmus /*! searches in both inputFormats & outputFormats */ 121794a204f0SStephan Aßmus status_t 121894a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info, 121994a204f0SStephan Aßmus uint32 formatType, translator_id id) 122094a204f0SStephan Aßmus { 122194a204f0SStephan Aßmus int32 formatCount; 122294a204f0SStephan Aßmus const translation_format* formats = OutputFormats(&formatCount); 122394a204f0SStephan Aßmus 122494a204f0SStephan Aßmus for (int i = 0; i <= 1; formats = InputFormats(&formatCount), i++) { 122594a204f0SStephan Aßmus if (PopulateInfoFromFormat(info, formatType, 122694a204f0SStephan Aßmus formats, formatCount) == B_OK) { 122794a204f0SStephan Aßmus info->translator = id; 122894a204f0SStephan Aßmus return B_OK; 122994a204f0SStephan Aßmus } 123094a204f0SStephan Aßmus } 123194a204f0SStephan Aßmus 123294a204f0SStephan Aßmus return B_ERROR; 123394a204f0SStephan Aßmus } 123494a204f0SStephan Aßmus 123594a204f0SStephan Aßmus 123694a204f0SStephan Aßmus status_t 123794a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info, 123894a204f0SStephan Aßmus uint32 formatType, const translation_format* formats, int32 formatCount) 123994a204f0SStephan Aßmus { 124094a204f0SStephan Aßmus for (int i = 0; i < formatCount; i++) { 124194a204f0SStephan Aßmus if (formats[i].type == formatType) { 124294a204f0SStephan Aßmus info->type = formatType; 124394a204f0SStephan Aßmus info->group = formats[i].group; 124494a204f0SStephan Aßmus info->quality = formats[i].quality; 124594a204f0SStephan Aßmus info->capability = formats[i].capability; 1246c44966dfSJérôme Duval if (strncmp(formats[i].name, 1247c44966dfSJérôme Duval "Be Bitmap Format (JPEG2000Translator)", 1248c44966dfSJérôme Duval sizeof("Be Bitmap Format (JPEG2000Translator)")) == 0) 1249c44966dfSJérôme Duval strncpy(info->name, 1250c44966dfSJérôme Duval B_TRANSLATE("Be Bitmap Format (JPEG2000Translator)"), 1251c44966dfSJérôme Duval sizeof(info->name)); 1252c44966dfSJérôme Duval else 1253c44966dfSJérôme Duval strncpy(info->name, formats[i].name, sizeof(info->name)); 1254c44966dfSJérôme Duval strncpy(info->MIME, formats[i].MIME, sizeof(info->MIME)); 125594a204f0SStephan Aßmus return B_OK; 125694a204f0SStephan Aßmus } 125794a204f0SStephan Aßmus } 125894a204f0SStephan Aßmus 125994a204f0SStephan Aßmus return B_ERROR; 126094a204f0SStephan Aßmus } 126194a204f0SStephan Aßmus 126294a204f0SStephan Aßmus 1263117da2d7SAxel Dörfler /*! 1264117da2d7SAxel Dörfler Frees jpeg alocated memory 1265117da2d7SAxel Dörfler Returns given error (B_ERROR by default) 1266117da2d7SAxel Dörfler */ 12679949213aSStephan Aßmus status_t 126813eaf8faSStephan Aßmus Error(jas_stream_t* stream, jas_image_t* image, jas_matrix_t** pixels, 126913eaf8faSStephan Aßmus int32 pixels_count, jpr_uchar_t* scanline, status_t error) 12709949213aSStephan Aßmus { 1271117da2d7SAxel Dörfler if (pixels) { 12729949213aSStephan Aßmus int32 i; 1273117da2d7SAxel Dörfler for (i = 0; i < (long)pixels_count; i++) { 12749949213aSStephan Aßmus if (pixels[i] != NULL) 12759949213aSStephan Aßmus jas_matrix_destroy(pixels[i]); 12769949213aSStephan Aßmus } 1277117da2d7SAxel Dörfler } 12789949213aSStephan Aßmus if (stream) 12799949213aSStephan Aßmus jas_stream_close(stream); 12809949213aSStephan Aßmus if (image) 12819949213aSStephan Aßmus jas_image_destroy(image); 1282117da2d7SAxel Dörfler 12839949213aSStephan Aßmus jas_image_clearfmts(); 12849949213aSStephan Aßmus free(scanline); 12859949213aSStephan Aßmus 12869949213aSStephan Aßmus return error; 12879949213aSStephan Aßmus } 1288117da2d7SAxel Dörfler 1289117da2d7SAxel Dörfler 1290117da2d7SAxel Dörfler // #pragma mark - 1291117da2d7SAxel Dörfler 129294a204f0SStephan Aßmus BTranslator* 129394a204f0SStephan Aßmus make_nth_translator(int32 n, image_id you, uint32 flags, ...) 129494a204f0SStephan Aßmus { 129594a204f0SStephan Aßmus if (!n) 129694a204f0SStephan Aßmus return new JP2Translator(); 129794a204f0SStephan Aßmus 129894a204f0SStephan Aßmus return NULL; 129994a204f0SStephan Aßmus } 130094a204f0SStephan Aßmus 1301117da2d7SAxel Dörfler 1302117da2d7SAxel Dörfler int 1303117da2d7SAxel Dörfler main() 1304117da2d7SAxel Dörfler { 1305117da2d7SAxel Dörfler BApplication app("application/x-vnd.Haiku-JPEG2000Translator"); 130694a204f0SStephan Aßmus JP2Translator* translator = new JP2Translator(); 130770d59669SSiarzhuk Zharski if (LaunchTranslatorWindow(translator, sTranslatorName) == B_OK) 1308117da2d7SAxel Dörfler app.Run(); 130994a204f0SStephan Aßmus 1310117da2d7SAxel Dörfler return 0; 1311117da2d7SAxel Dörfler } 1312117da2d7SAxel Dörfler 1313