xref: /haiku/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp (revision 546208a53940a26c6379c48a7854ade1a8250fc5)
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 
4094a204f0SStephan Aßmus #include <GroupLayoutBuilder.h>
41117da2d7SAxel Dörfler #include <TabView.h>
4294a204f0SStephan Aßmus #include <TextView.h>
43117da2d7SAxel Dörfler 
449949213aSStephan Aßmus 
45*546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
46*546208a5SOliver 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;
56994a204f0SStephan Aßmus 	AddChild(BGroupLayoutBuilder(B_VERTICAL)
57094a204f0SStephan Aßmus 		.Add(fGrayAsRGB32)
57194a204f0SStephan Aßmus 		.AddGlue()
57294a204f0SStephan Aßmus 		.SetInsets(padding, padding, padding, padding)
57394a204f0SStephan Aßmus 	);
57494a204f0SStephan Aßmus }
57594a204f0SStephan Aßmus 
57694a204f0SStephan Aßmus 
57794a204f0SStephan Aßmus TranslatorReadView::~TranslatorReadView()
57894a204f0SStephan Aßmus {
57994a204f0SStephan Aßmus 	fSettings->Release();
5809949213aSStephan Aßmus }
5819949213aSStephan Aßmus 
582117da2d7SAxel Dörfler 
5839949213aSStephan Aßmus void
5849949213aSStephan Aßmus TranslatorReadView::AttachedToWindow()
5859949213aSStephan Aßmus {
586117da2d7SAxel Dörfler 	fGrayAsRGB32->SetTarget(this);
5879949213aSStephan Aßmus }
5889949213aSStephan Aßmus 
589117da2d7SAxel Dörfler 
5909949213aSStephan Aßmus void
5919949213aSStephan Aßmus TranslatorReadView::MessageReceived(BMessage* message)
5929949213aSStephan Aßmus {
593117da2d7SAxel Dörfler 	switch (message->what) {
5949949213aSStephan Aßmus 		case VIEW_MSG_SET_GRAYASRGB32:
5959949213aSStephan Aßmus 		{
5969949213aSStephan Aßmus 			int32 value;
5979949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
59894a204f0SStephan Aßmus 				bool boolValue = value;
59994a204f0SStephan Aßmus 				fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32, &boolValue);
60094a204f0SStephan Aßmus 				fSettings->SaveSettings();
6019949213aSStephan Aßmus 			}
6029949213aSStephan Aßmus 			break;
6039949213aSStephan Aßmus 		}
6049949213aSStephan Aßmus 		default:
6059949213aSStephan Aßmus 			BView::MessageReceived(message);
6069949213aSStephan Aßmus 			break;
6079949213aSStephan Aßmus 	}
6089949213aSStephan Aßmus }
6099949213aSStephan Aßmus 
6109949213aSStephan Aßmus 
611117da2d7SAxel Dörfler //	#pragma mark - TranslatorWriteView
6129949213aSStephan Aßmus 
613117da2d7SAxel Dörfler 
61494a204f0SStephan Aßmus TranslatorWriteView::TranslatorWriteView(const char* name,
61594a204f0SStephan Aßmus 	TranslatorSettings* settings)
61694a204f0SStephan Aßmus 	:
61794a204f0SStephan Aßmus 	BView(name, 0, new BGroupLayout(B_VERTICAL)),
618117da2d7SAxel Dörfler 	fSettings(settings)
6199949213aSStephan Aßmus {
6202e49ff35SSiarzhuk Zharski 	fQualitySlider = new SSlider("quality", B_TRANSLATE("Output quality"),
62194a204f0SStephan Aßmus 		new BMessage(VIEW_MSG_SET_QUALITY), 0, 100);
622117da2d7SAxel Dörfler 	fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
623117da2d7SAxel Dörfler 	fQualitySlider->SetHashMarkCount(10);
624c44966dfSJérôme Duval 	fQualitySlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High"));
62594a204f0SStephan Aßmus 	fQualitySlider->SetValue(fSettings->SetGetInt32(JP2_SET_QUALITY));
6269949213aSStephan Aßmus 
6272e49ff35SSiarzhuk Zharski 	fGrayAsRGB24 = new BCheckBox("gray1asrgb24",
6282e49ff35SSiarzhuk Zharski 		B_TRANSLATE("Write black-and-white images as RGB24"),
629117da2d7SAxel Dörfler 		new BMessage(VIEW_MSG_SET_GRAY1ASRGB24));
63094a204f0SStephan Aßmus 	if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24))
63194a204f0SStephan Aßmus 		fGrayAsRGB24->SetValue(B_CONTROL_ON);
6329949213aSStephan Aßmus 
6332e49ff35SSiarzhuk Zharski 	fCodeStreamOnly = new BCheckBox("codestreamonly",
6342e49ff35SSiarzhuk Zharski 		B_TRANSLATE("Output only codestream (.jpc)"),
63594a204f0SStephan Aßmus 		new BMessage(VIEW_MSG_SET_JPC));
63694a204f0SStephan Aßmus 	if (fSettings->SetGetBool(JP2_SET_JPC))
63794a204f0SStephan Aßmus 		fCodeStreamOnly->SetValue(B_CONTROL_ON);
6389949213aSStephan Aßmus 
63994a204f0SStephan Aßmus 	float padding = 10.0f;
64094a204f0SStephan Aßmus 	AddChild(BGroupLayoutBuilder(B_VERTICAL, padding)
64194a204f0SStephan Aßmus 		.Add(fQualitySlider)
64294a204f0SStephan Aßmus 		.Add(fGrayAsRGB24)
64394a204f0SStephan Aßmus 		.Add(fCodeStreamOnly)
64494a204f0SStephan Aßmus 		.AddGlue()
64594a204f0SStephan Aßmus 		.SetInsets(padding, padding, padding, padding)
64694a204f0SStephan Aßmus 	);
64794a204f0SStephan Aßmus }
648bdaaeb0cSStefano Ceccherini 
6499949213aSStephan Aßmus 
65094a204f0SStephan Aßmus TranslatorWriteView::~TranslatorWriteView()
65194a204f0SStephan Aßmus {
65294a204f0SStephan Aßmus 	fSettings->Release();
6539949213aSStephan Aßmus }
6549949213aSStephan Aßmus 
655117da2d7SAxel Dörfler 
6569949213aSStephan Aßmus void
6579949213aSStephan Aßmus TranslatorWriteView::AttachedToWindow()
6589949213aSStephan Aßmus {
659117da2d7SAxel Dörfler 	fQualitySlider->SetTarget(this);
660117da2d7SAxel Dörfler 	fGrayAsRGB24->SetTarget(this);
661117da2d7SAxel Dörfler 	fCodeStreamOnly->SetTarget(this);
6629949213aSStephan Aßmus }
6639949213aSStephan Aßmus 
664117da2d7SAxel Dörfler 
6659949213aSStephan Aßmus void
6669949213aSStephan Aßmus TranslatorWriteView::MessageReceived(BMessage* message)
6679949213aSStephan Aßmus {
668117da2d7SAxel Dörfler 	switch (message->what) {
6699949213aSStephan Aßmus 		case VIEW_MSG_SET_QUALITY:
6709949213aSStephan Aßmus 		{
6719949213aSStephan Aßmus 			int32 value;
6729949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
67394a204f0SStephan Aßmus 				fSettings->SetGetInt32(JP2_SET_QUALITY, &value);
67494a204f0SStephan Aßmus 				fSettings->SaveSettings();
6759949213aSStephan Aßmus 			}
6769949213aSStephan Aßmus 			break;
6779949213aSStephan Aßmus 		}
6789949213aSStephan Aßmus 		case VIEW_MSG_SET_GRAY1ASRGB24:
6799949213aSStephan Aßmus 		{
6809949213aSStephan Aßmus 			int32 value;
6819949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
68294a204f0SStephan Aßmus 				bool boolValue = value;
68394a204f0SStephan Aßmus 				fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24, &boolValue);
68494a204f0SStephan Aßmus 				fSettings->SaveSettings();
6859949213aSStephan Aßmus 			}
6869949213aSStephan Aßmus 			break;
6879949213aSStephan Aßmus 		}
6889949213aSStephan Aßmus 		case VIEW_MSG_SET_JPC:
6899949213aSStephan Aßmus 		{
6909949213aSStephan Aßmus 			int32 value;
6919949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
69294a204f0SStephan Aßmus 				bool boolValue = value;
69394a204f0SStephan Aßmus 				fSettings->SetGetBool(JP2_SET_JPC, &boolValue);
69494a204f0SStephan Aßmus 				fSettings->SaveSettings();
6959949213aSStephan Aßmus 			}
6969949213aSStephan Aßmus 			break;
6979949213aSStephan Aßmus 		}
6989949213aSStephan Aßmus 		default:
6999949213aSStephan Aßmus 			BView::MessageReceived(message);
7009949213aSStephan Aßmus 			break;
7019949213aSStephan Aßmus 	}
7029949213aSStephan Aßmus }
7039949213aSStephan Aßmus 
7049949213aSStephan Aßmus 
705117da2d7SAxel Dörfler //	#pragma mark -
7069949213aSStephan Aßmus 
707117da2d7SAxel Dörfler 
70894a204f0SStephan Aßmus TranslatorAboutView::TranslatorAboutView(const char* name)
70994a204f0SStephan Aßmus 	:
71094a204f0SStephan Aßmus 	BView(name, 0, new BGroupLayout(B_VERTICAL))
7119949213aSStephan Aßmus {
71294a204f0SStephan Aßmus 	BAlignment labelAlignment = BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
7132e49ff35SSiarzhuk Zharski 	BStringView* title = new BStringView("Title", sTranslatorName);
7149949213aSStephan Aßmus 	title->SetFont(be_bold_font);
71594a204f0SStephan Aßmus 	title->SetExplicitAlignment(labelAlignment);
7169949213aSStephan Aßmus 
7179949213aSStephan Aßmus 	char versionString[16];
718c44966dfSJérôme Duval 	sprintf(versionString, "v%d.%d.%d",
719c44966dfSJérôme Duval 		static_cast<int>(sTranslatorVersion >> 8),
720c44966dfSJérôme Duval 		static_cast<int>((sTranslatorVersion >> 4) & 0xf),
721c44966dfSJérôme Duval 		static_cast<int>(sTranslatorVersion & 0xf));
7229949213aSStephan Aßmus 
72394a204f0SStephan Aßmus 	BStringView* version = new BStringView("Version", versionString);
72494a204f0SStephan Aßmus 	version->SetExplicitAlignment(labelAlignment);
7259949213aSStephan Aßmus 
72694a204f0SStephan Aßmus 	BTextView* infoView = new BTextView("info");
7272e49ff35SSiarzhuk Zharski 	infoView->SetText(sTranslatorInfo);
72894a204f0SStephan Aßmus 	infoView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
72994a204f0SStephan Aßmus 	infoView->MakeEditable(false);
7309949213aSStephan Aßmus 
73194a204f0SStephan Aßmus 	float padding = 10.0f;
73294a204f0SStephan Aßmus 	AddChild(BGroupLayoutBuilder(B_VERTICAL, padding)
73394a204f0SStephan Aßmus 		.Add(BGroupLayoutBuilder(B_HORIZONTAL, padding)
73494a204f0SStephan Aßmus 			.Add(title)
73594a204f0SStephan Aßmus 			.Add(version)
73694a204f0SStephan Aßmus 			.AddGlue()
73794a204f0SStephan Aßmus 		)
73894a204f0SStephan Aßmus 		.Add(infoView)
73994a204f0SStephan Aßmus 		.SetInsets(padding, padding, padding, padding)
74094a204f0SStephan Aßmus 	);
7419949213aSStephan Aßmus }
7429949213aSStephan Aßmus 
7439949213aSStephan Aßmus 
744117da2d7SAxel Dörfler //	#pragma mark -
7459949213aSStephan Aßmus 
746117da2d7SAxel Dörfler 
74794a204f0SStephan Aßmus TranslatorView::TranslatorView(const char* name, TranslatorSettings* settings)
74894a204f0SStephan Aßmus 	:
74994a204f0SStephan Aßmus 	BTabView(name)
7509949213aSStephan Aßmus {
751c44966dfSJérôme Duval 	AddTab(new TranslatorWriteView(B_TRANSLATE("Write"),
752c44966dfSJérôme Duval 		settings->Acquire()));
753c44966dfSJérôme Duval 	AddTab(new TranslatorReadView(B_TRANSLATE("Read"),
754c44966dfSJérôme Duval 		settings->Acquire()));
755c44966dfSJérôme Duval 	AddTab(new TranslatorAboutView(B_TRANSLATE("About")));
7569949213aSStephan Aßmus 
75794a204f0SStephan Aßmus 	settings->Release();
7589949213aSStephan Aßmus 
75994a204f0SStephan Aßmus  	BFont font;
76094a204f0SStephan Aßmus  	GetFont(&font);
76194a204f0SStephan Aßmus  	SetExplicitPreferredSize(
76294a204f0SStephan Aßmus 		BSize((font.Size() * 380) / 12, (font.Size() * 250) / 12));
7639949213aSStephan Aßmus }
7649949213aSStephan Aßmus 
7659949213aSStephan Aßmus 
766117da2d7SAxel Dörfler //	#pragma mark -
7679949213aSStephan Aßmus 
76894a204f0SStephan Aßmus BView*
76994a204f0SStephan Aßmus JP2Translator::NewConfigView(TranslatorSettings* settings)
7709949213aSStephan Aßmus {
77194a204f0SStephan Aßmus 	BView* outView = new TranslatorView("TranslatorView", settings);
77294a204f0SStephan Aßmus 	return outView;
7739949213aSStephan Aßmus }
7749949213aSStephan Aßmus 
7759949213aSStephan Aßmus 
77694a204f0SStephan Aßmus JP2Translator::JP2Translator()
777bf243977SPhilippe Houdoin 	: BaseTranslator(sTranslatorName, sTranslatorInfo, sTranslatorVersion,
778bf243977SPhilippe Houdoin 		sInputFormats, kNumInputFormats,
779bf243977SPhilippe Houdoin 		sOutputFormats, kNumOutputFormats,
780bf243977SPhilippe Houdoin 		JP2_SETTINGS_FILE,
781bf243977SPhilippe Houdoin 		sDefaultSettings, kNumDefaultSettings,
782bf243977SPhilippe Houdoin 		B_TRANSLATOR_BITMAP, JP2_FORMAT)
7839949213aSStephan Aßmus {
7849949213aSStephan Aßmus }
7859949213aSStephan Aßmus 
786117da2d7SAxel Dörfler 
787117da2d7SAxel Dörfler //!	Determine whether or not we can handle this data
7889949213aSStephan Aßmus status_t
78994a204f0SStephan Aßmus JP2Translator::DerivedIdentify(BPositionIO* inSource,
79094a204f0SStephan Aßmus 	const translation_format* inFormat, BMessage* ioExtension,
79194a204f0SStephan Aßmus 	translator_info* outInfo, uint32 outType)
7929949213aSStephan Aßmus {
79313eaf8faSStephan Aßmus 	if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP)
79413eaf8faSStephan Aßmus 		&& outType != JP2_FORMAT)
7959949213aSStephan Aßmus 		return B_NO_TRANSLATOR;
7969949213aSStephan Aßmus 
79713eaf8faSStephan Aßmus 	// !!! You might need to make this buffer bigger to test for your
79813eaf8faSStephan Aßmus 	// native format
7999949213aSStephan Aßmus 	off_t position = inSource->Position();
8009949213aSStephan Aßmus 	uint8 header[sizeof(TranslatorBitmap)];
8019949213aSStephan Aßmus 	status_t err = inSource->Read(header, sizeof(TranslatorBitmap));
8029949213aSStephan Aßmus 	inSource->Seek(position, SEEK_SET);
803117da2d7SAxel Dörfler 	if (err < B_OK)
804117da2d7SAxel Dörfler 		return err;
8059949213aSStephan Aßmus 
80613eaf8faSStephan Aßmus 	if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic)
80713eaf8faSStephan Aßmus 		== B_TRANSLATOR_BITMAP) {
80894a204f0SStephan Aßmus 		if (PopulateInfoFromFormat(outInfo, B_TRANSLATOR_BITMAP) != B_OK)
80994a204f0SStephan Aßmus 			return B_NO_TRANSLATOR;
8109949213aSStephan Aßmus 	} else {
81113eaf8faSStephan Aßmus 		if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8)
81213eaf8faSStephan Aßmus 			| header[7]) == JP2_BOX_JP) // JP2
81313eaf8faSStephan Aßmus 			|| (header[0] == (JPC_MS_SOC >> 8) && header[1]
81413eaf8faSStephan Aßmus 			== (JPC_MS_SOC & 0xff)))	// JPC
8159949213aSStephan Aßmus 		{
81694a204f0SStephan Aßmus 			if (PopulateInfoFromFormat(outInfo, JP2_FORMAT) != B_OK)
81794a204f0SStephan Aßmus 				return B_NO_TRANSLATOR;
8189949213aSStephan Aßmus 		} else
8199949213aSStephan Aßmus 			return B_NO_TRANSLATOR;
8209949213aSStephan Aßmus 	}
8219949213aSStephan Aßmus 
8229949213aSStephan Aßmus 	return B_OK;
8239949213aSStephan Aßmus }
8249949213aSStephan Aßmus 
825117da2d7SAxel Dörfler 
8269949213aSStephan Aßmus status_t
82794a204f0SStephan Aßmus JP2Translator::DerivedTranslate(BPositionIO* inSource,
82894a204f0SStephan Aßmus 	const translator_info* inInfo, BMessage* ioExtension, uint32 outType,
82994a204f0SStephan Aßmus 	BPositionIO* outDestination, int32 baseType)
8309949213aSStephan Aßmus {
8319949213aSStephan Aßmus 	// If no specific type was requested, convert to the interchange format
832117da2d7SAxel Dörfler 	if (outType == 0)
833117da2d7SAxel Dörfler 		outType = B_TRANSLATOR_BITMAP;
8349949213aSStephan Aßmus 
8359949213aSStephan Aßmus 	// What action to take, based on the findings of Identify()
836117da2d7SAxel Dörfler 	if (outType == inInfo->type)
8379949213aSStephan Aßmus 		return Copy(inSource, outDestination);
838117da2d7SAxel Dörfler 	if (inInfo->type == B_TRANSLATOR_BITMAP && outType == JP2_FORMAT)
8399949213aSStephan Aßmus 		return Compress(inSource, outDestination);
840117da2d7SAxel Dörfler 	if (inInfo->type == JP2_FORMAT && outType == B_TRANSLATOR_BITMAP)
8419949213aSStephan Aßmus 		return Decompress(inSource, outDestination);
8429949213aSStephan Aßmus 
8439949213aSStephan Aßmus 	return B_NO_TRANSLATOR;
8449949213aSStephan Aßmus }
8459949213aSStephan Aßmus 
846117da2d7SAxel Dörfler 
847117da2d7SAxel Dörfler //!	The user has requested the same format for input and output, so just copy
8489949213aSStephan Aßmus status_t
84994a204f0SStephan Aßmus JP2Translator::Copy(BPositionIO* in, BPositionIO* out)
8509949213aSStephan Aßmus {
8519949213aSStephan Aßmus 	int block_size = 65536;
8529949213aSStephan Aßmus 	void* buffer = malloc(block_size);
8539949213aSStephan Aßmus 	char temp[1024];
8549949213aSStephan Aßmus 	if (buffer == NULL) {
8559949213aSStephan Aßmus 		buffer = temp;
8569949213aSStephan Aßmus 		block_size = 1024;
8579949213aSStephan Aßmus 	}
8589949213aSStephan Aßmus 	status_t err = B_OK;
8599949213aSStephan Aßmus 
8609949213aSStephan Aßmus 	// Read until end of file or error
8619949213aSStephan Aßmus 	while (1) {
8629949213aSStephan Aßmus 		ssize_t to_read = block_size;
8639949213aSStephan Aßmus 		err = in->Read(buffer, to_read);
8649949213aSStephan Aßmus 		// Explicit check for EOF
8659949213aSStephan Aßmus 		if (err == -1) {
866117da2d7SAxel Dörfler 			if (buffer != temp)
867117da2d7SAxel Dörfler 				free(buffer);
8689949213aSStephan Aßmus 			return B_OK;
8699949213aSStephan Aßmus 		}
8709949213aSStephan Aßmus 		if (err <= B_OK) break;
8719949213aSStephan Aßmus 		to_read = err;
8729949213aSStephan Aßmus 		err = out->Write(buffer, to_read);
8739949213aSStephan Aßmus 		if (err != to_read) if (err >= 0) err = B_DEVICE_FULL;
8749949213aSStephan Aßmus 		if (err < B_OK) break;
8759949213aSStephan Aßmus 	}
8769949213aSStephan Aßmus 
877117da2d7SAxel Dörfler 	if (buffer != temp)
878117da2d7SAxel Dörfler 		free(buffer);
8799949213aSStephan Aßmus 	return (err >= 0) ? B_OK : err;
8809949213aSStephan Aßmus }
8819949213aSStephan Aßmus 
882117da2d7SAxel Dörfler 
883117da2d7SAxel Dörfler //!	Encode into the native format
8849949213aSStephan Aßmus status_t
88594a204f0SStephan Aßmus JP2Translator::Compress(BPositionIO* in, BPositionIO* out)
8869949213aSStephan Aßmus {
88794a204f0SStephan Aßmus 	using namespace conversion;
8889949213aSStephan Aßmus 
8899949213aSStephan Aßmus 	// Read info about bitmap
8909949213aSStephan Aßmus 	TranslatorBitmap header;
8919949213aSStephan Aßmus 	status_t err = in->Read(&header, sizeof(TranslatorBitmap));
892117da2d7SAxel Dörfler 	if (err < B_OK)
893117da2d7SAxel Dörfler 		return err;
894117da2d7SAxel Dörfler 	if (err < (int)sizeof(TranslatorBitmap))
895117da2d7SAxel Dörfler 		return B_ERROR;
8969949213aSStephan Aßmus 
8979949213aSStephan Aßmus 	// Grab dimension, color space, and size information from the stream
8989949213aSStephan Aßmus 	BRect bounds;
8999949213aSStephan Aßmus 	bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left);
9009949213aSStephan Aßmus 	bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top);
9019949213aSStephan Aßmus 	bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right);
9029949213aSStephan Aßmus 	bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
9039949213aSStephan Aßmus 
9049949213aSStephan Aßmus 	int32 in_row_bytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
9059949213aSStephan Aßmus 
9069949213aSStephan Aßmus 	int width = bounds.IntegerWidth() + 1;
9079949213aSStephan Aßmus 	int height = bounds.IntegerHeight() + 1;
9089949213aSStephan Aßmus 
9099949213aSStephan Aßmus 	// Function pointer to write function
9109949213aSStephan Aßmus 	// It MUST point to proper function
91113eaf8faSStephan Aßmus 	void (*converter)(jas_matrix_t** pixels, jpr_uchar_t* inscanline,
91213eaf8faSStephan Aßmus 		int width) = write_rgba32;
9139949213aSStephan Aßmus 
9149949213aSStephan Aßmus 	// Default color info
9159949213aSStephan Aßmus 	int out_color_space = JAS_IMAGE_CS_RGB;
9169949213aSStephan Aßmus 	int out_color_components = 3;
9179949213aSStephan Aßmus 
918117da2d7SAxel Dörfler 	switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) {
9199949213aSStephan Aßmus 		case B_GRAY1:
92094a204f0SStephan Aßmus 			if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) {
9219949213aSStephan Aßmus 				converter = write_gray1_to_rgb24;
9229949213aSStephan Aßmus 			} else {
9239949213aSStephan Aßmus 				out_color_components = 1;
9249949213aSStephan Aßmus 				out_color_space = JAS_IMAGE_CS_GRAY;
9259949213aSStephan Aßmus 				converter = write_gray1_to_gray;
9269949213aSStephan Aßmus 			}
9279949213aSStephan Aßmus 			break;
928117da2d7SAxel Dörfler 
9299949213aSStephan Aßmus 		case B_CMAP8:
9309949213aSStephan Aßmus 			converter = write_cmap8_to_rgb24;
9319949213aSStephan Aßmus 			break;
932117da2d7SAxel Dörfler 
9339949213aSStephan Aßmus 		case B_GRAY8:
9349949213aSStephan Aßmus 			out_color_components = 1;
9359949213aSStephan Aßmus 			out_color_space = JAS_IMAGE_CS_GRAY;
9369949213aSStephan Aßmus 			converter = write_gray;
9379949213aSStephan Aßmus 			break;
938117da2d7SAxel Dörfler 
9399949213aSStephan Aßmus 		case B_RGB15:
9409949213aSStephan Aßmus 		case B_RGBA15:
9419949213aSStephan Aßmus 			converter = write_rgb15_to_rgb24;
9429949213aSStephan Aßmus 			break;
943117da2d7SAxel Dörfler 
9449949213aSStephan Aßmus 		case B_RGB15_BIG:
9459949213aSStephan Aßmus 		case B_RGBA15_BIG:
9469949213aSStephan Aßmus 			converter = write_rgb15b_to_rgb24;
9479949213aSStephan Aßmus 			break;
948117da2d7SAxel Dörfler 
9499949213aSStephan Aßmus 		case B_RGB16:
9509949213aSStephan Aßmus 			converter = write_rgb16_to_rgb24;
9519949213aSStephan Aßmus 			break;
952117da2d7SAxel Dörfler 
9539949213aSStephan Aßmus 		case B_RGB16_BIG:
9549949213aSStephan Aßmus 			converter = write_rgb16b_to_rgb24;
9559949213aSStephan Aßmus 			break;
956117da2d7SAxel Dörfler 
9579949213aSStephan Aßmus 		case B_RGB24:
9589949213aSStephan Aßmus 			converter = write_rgb24;
9599949213aSStephan Aßmus 			break;
960117da2d7SAxel Dörfler 
9619949213aSStephan Aßmus 		case B_RGB24_BIG:
9629949213aSStephan Aßmus 			converter = write_rgb24b;
9639949213aSStephan Aßmus 			break;
964117da2d7SAxel Dörfler 
9659949213aSStephan Aßmus 		case B_RGB32:
9669949213aSStephan Aßmus 			converter = write_rgb32_to_rgb24;
9679949213aSStephan Aßmus 			break;
968117da2d7SAxel Dörfler 
9699949213aSStephan Aßmus 		case B_RGB32_BIG:
9709949213aSStephan Aßmus 			converter = write_rgb32b_to_rgb24;
9719949213aSStephan Aßmus 			break;
972117da2d7SAxel Dörfler 
9739949213aSStephan Aßmus 		case B_RGBA32:
9749949213aSStephan Aßmus 		/*
9759949213aSStephan Aßmus 			// In theory it should be possible to write 4 color components
9769949213aSStephan Aßmus 			// to jp2, so it should be possible to have transparency.
9779949213aSStephan Aßmus 			// Unfortunetly libjasper does not agree with that
9789949213aSStephan Aßmus 			// For now i don't know how to modify it :(
9799949213aSStephan Aßmus 
9809949213aSStephan Aßmus 			out_color_components = 4;
9819949213aSStephan Aßmus 			converter = write_rgba32;
9829949213aSStephan Aßmus 		*/
9839949213aSStephan Aßmus 			converter = write_rgb32_to_rgb24;
9849949213aSStephan Aßmus 			break;
985117da2d7SAxel Dörfler 
9869949213aSStephan Aßmus 		case B_RGBA32_BIG:
9879949213aSStephan Aßmus 		/*
9889949213aSStephan Aßmus 			// In theory it should be possible to write 4 color components
9899949213aSStephan Aßmus 			// to jp2, so it should be possible to have transparency.
9909949213aSStephan Aßmus 			// Unfortunetly libjasper does not agree with that
9919949213aSStephan Aßmus 			// For now i don't know how to modify it :(
9929949213aSStephan Aßmus 
9939949213aSStephan Aßmus 			out_color_components = 4;
9949949213aSStephan Aßmus 			converter = write_rgba32b;
9959949213aSStephan Aßmus 		*/
9969949213aSStephan Aßmus 			converter = write_rgb32b_to_rgb24;
9979949213aSStephan Aßmus 			break;
998117da2d7SAxel Dörfler 
9999949213aSStephan Aßmus 		default:
100070d59669SSiarzhuk Zharski 			syslog(LOG_ERR, "Unknown color space.\n");
10019949213aSStephan Aßmus 			return B_ERROR;
10029949213aSStephan Aßmus 	}
10039949213aSStephan Aßmus 
10049949213aSStephan Aßmus 	jas_image_t* image;
10059949213aSStephan Aßmus 	jas_stream_t* outs;
10069949213aSStephan Aßmus 	jas_matrix_t* pixels[4];
10079949213aSStephan Aßmus 	jas_image_cmptparm_t component_info[4];
10089949213aSStephan Aßmus 
10099949213aSStephan Aßmus 	if (jas_init())
10109949213aSStephan Aßmus 		return B_ERROR;
10119949213aSStephan Aßmus 
10129949213aSStephan Aßmus 	if (!(outs = jas_stream_positionIOopen(out)))
10139949213aSStephan Aßmus 		return B_ERROR;
10149949213aSStephan Aßmus 
10159949213aSStephan Aßmus 	int32 i = 0;
1016117da2d7SAxel Dörfler 	for (i = 0; i < (long)out_color_components; i++) {
10179949213aSStephan Aßmus 		(void) memset(component_info + i, 0, sizeof(jas_image_cmptparm_t));
10189949213aSStephan Aßmus 		component_info[i].hstep = 1;
10199949213aSStephan Aßmus 		component_info[i].vstep = 1;
10209949213aSStephan Aßmus 		component_info[i].width = (unsigned int)width;
10219949213aSStephan Aßmus 		component_info[i].height = (unsigned int)height;
10229949213aSStephan Aßmus 		component_info[i].prec = (unsigned int)8;
10239949213aSStephan Aßmus 	}
10249949213aSStephan Aßmus 
102513eaf8faSStephan Aßmus 	image = jas_image_create((short)out_color_components, component_info,
102613eaf8faSStephan Aßmus 		out_color_space);
10279949213aSStephan Aßmus 	if (image == (jas_image_t *)NULL)
10289949213aSStephan Aßmus 		return Error(outs, NULL, NULL, 0, NULL, B_ERROR);
10299949213aSStephan Aßmus 
10309949213aSStephan Aßmus 	jpr_uchar_t *in_scanline = (jpr_uchar_t*) malloc(in_row_bytes);
1031117da2d7SAxel Dörfler 	if (in_scanline == NULL)
1032117da2d7SAxel Dörfler 		return Error(outs, image, NULL, 0, NULL, B_ERROR);
10339949213aSStephan Aßmus 
1034117da2d7SAxel Dörfler 	for (i = 0; i < (long)out_color_components; i++) {
10359949213aSStephan Aßmus 		pixels[i] = jas_matrix_create(1, (unsigned int)width);
10369949213aSStephan Aßmus 		if (pixels[i] == (jas_matrix_t *)NULL)
10379949213aSStephan Aßmus 			return Error(outs, image, pixels, i+1, in_scanline, B_ERROR);
10389949213aSStephan Aßmus 	}
10399949213aSStephan Aßmus 
10409949213aSStephan Aßmus 	int32 y = 0;
1041117da2d7SAxel Dörfler 	for (y = 0; y < (long)height; y++) {
10429949213aSStephan Aßmus 		err = in->Read(in_scanline, in_row_bytes);
104313eaf8faSStephan Aßmus 		if (err < in_row_bytes) {
104494a204f0SStephan Aßmus 			return (err < B_OK) ? Error(outs, image, pixels,
104594a204f0SStephan Aßmus 					out_color_components, in_scanline, err)
104613eaf8faSStephan Aßmus 				: Error(outs, image, pixels, out_color_components, in_scanline,
104713eaf8faSStephan Aßmus 					B_ERROR);
104813eaf8faSStephan Aßmus 		}
10499949213aSStephan Aßmus 
10509949213aSStephan Aßmus 		converter(pixels, in_scanline, width);
10519949213aSStephan Aßmus 
105213eaf8faSStephan Aßmus 		for (i = 0; i < (long)out_color_components; i++) {
105313eaf8faSStephan Aßmus 			(void)jas_image_writecmpt(image, (short)i, 0, (unsigned int)y,
105413eaf8faSStephan Aßmus 				(unsigned int)width, 1, pixels[i]);
105513eaf8faSStephan Aßmus 		}
10569949213aSStephan Aßmus 	}
10579949213aSStephan Aßmus 
10589949213aSStephan Aßmus 	char opts[16];
105994a204f0SStephan Aßmus 	sprintf(opts, "rate=%1f",
106094a204f0SStephan Aßmus 		(float)fSettings->SetGetInt32(JP2_SET_QUALITY) / 100.0);
106194a204f0SStephan Aßmus 
106294a204f0SStephan Aßmus 	if (jas_image_encode(image, outs, jas_image_strtofmt(
106394a204f0SStephan Aßmus 			fSettings->SetGetBool(JP2_SET_JPC) ?
106413eaf8faSStephan Aßmus 				(char*)"jpc" : (char*)"jp2"), opts)) {
106594a204f0SStephan Aßmus 		return Error(outs, image, pixels,
106694a204f0SStephan Aßmus 			out_color_components, in_scanline, err);
106713eaf8faSStephan Aßmus 	}
10689949213aSStephan Aßmus 
10699949213aSStephan Aßmus 	free(in_scanline);
10709949213aSStephan Aßmus 
10719949213aSStephan Aßmus 	for (i = 0; i < (long)out_color_components; i++)
10729949213aSStephan Aßmus 		jas_matrix_destroy(pixels[i]);
1073117da2d7SAxel Dörfler 
10749949213aSStephan Aßmus 	jas_stream_close(outs);
10759949213aSStephan Aßmus 	jas_image_destroy(image);
10769949213aSStephan Aßmus 	jas_image_clearfmts();
10779949213aSStephan Aßmus 
10789949213aSStephan Aßmus 	return B_OK;
10799949213aSStephan Aßmus }
10809949213aSStephan Aßmus 
1081117da2d7SAxel Dörfler 
1082117da2d7SAxel Dörfler //!	Decode the native format
10839949213aSStephan Aßmus status_t
108494a204f0SStephan Aßmus JP2Translator::Decompress(BPositionIO* in, BPositionIO* out)
10859949213aSStephan Aßmus {
108694a204f0SStephan Aßmus 	using namespace conversion;
10879949213aSStephan Aßmus 
10889949213aSStephan Aßmus 	jas_image_t* image;
10899949213aSStephan Aßmus 	jas_stream_t* ins;
10909949213aSStephan Aßmus 	jas_matrix_t* pixels[4];
10919949213aSStephan Aßmus 
10929949213aSStephan Aßmus 	if (jas_init())
10939949213aSStephan Aßmus 		return B_ERROR;
10949949213aSStephan Aßmus 
10959949213aSStephan Aßmus 	if (!(ins = jas_stream_positionIOopen(in)))
10969949213aSStephan Aßmus 		return B_ERROR;
10979949213aSStephan Aßmus 
10989949213aSStephan Aßmus 	if (!(image = jas_image_decode(ins, -1, 0)))
10999949213aSStephan Aßmus 		return Error(ins, NULL, NULL, 0, NULL, B_ERROR);
11009949213aSStephan Aßmus 
11019949213aSStephan Aßmus 	// Default color info
11029949213aSStephan Aßmus 	color_space out_color_space;
11039949213aSStephan Aßmus 	int out_color_components;
11049949213aSStephan Aßmus 	int	in_color_components = jas_image_numcmpts(image);
11059949213aSStephan Aßmus 
11069949213aSStephan Aßmus 	// Function pointer to read function
11079949213aSStephan Aßmus 	// It MUST point to proper function
110813eaf8faSStephan Aßmus 	void (*converter)(jas_matrix_t** pixels, jpr_uchar_t* outscanline,
110913eaf8faSStephan Aßmus 		int width) = NULL;
11109949213aSStephan Aßmus 
1111117da2d7SAxel Dörfler 	switch (jas_image_colorspace(image)) {
11129949213aSStephan Aßmus 		case JAS_IMAGE_CS_RGB:
11139949213aSStephan Aßmus 			out_color_components = 4;
11149949213aSStephan Aßmus 			if (in_color_components == 3) {
11159949213aSStephan Aßmus 				out_color_space = B_RGB32;
11169949213aSStephan Aßmus 				converter = read_rgb24_to_rgb32;
11179949213aSStephan Aßmus 			} else if (in_color_components == 4) {
11189949213aSStephan Aßmus 				out_color_space = B_RGBA32;
11199949213aSStephan Aßmus 				converter = read_rgba32;
11209949213aSStephan Aßmus 			} else {
112170d59669SSiarzhuk Zharski 				syslog(LOG_ERR, "Other than RGB with 3 or 4 color "
112270d59669SSiarzhuk Zharski 					"components not implemented.\n");
11239949213aSStephan Aßmus 				return Error(ins, image, NULL, 0, NULL, B_ERROR);
11249949213aSStephan Aßmus 			}
11259949213aSStephan Aßmus 			break;
11269949213aSStephan Aßmus 		case JAS_IMAGE_CS_GRAY:
112794a204f0SStephan Aßmus 			if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) {
11289949213aSStephan Aßmus 				out_color_space = B_RGB32;
11299949213aSStephan Aßmus 				out_color_components = 4;
11309949213aSStephan Aßmus 				converter = read_gray_to_rgb32;
11319949213aSStephan Aßmus 			} else {
11329949213aSStephan Aßmus 				out_color_space = B_GRAY8;
11339949213aSStephan Aßmus 				out_color_components = 1;
11349949213aSStephan Aßmus 				converter = read_gray;
11359949213aSStephan Aßmus 			}
11369949213aSStephan Aßmus 			break;
11379949213aSStephan Aßmus 		case JAS_IMAGE_CS_YCBCR:
113870d59669SSiarzhuk Zharski 			syslog(LOG_ERR, "Color space YCBCR not implemented yet.\n");
11399949213aSStephan Aßmus 			return Error(ins, image, NULL, 0, NULL, B_ERROR);
11409949213aSStephan Aßmus 			break;
11419949213aSStephan Aßmus 		case JAS_IMAGE_CS_UNKNOWN:
11429949213aSStephan Aßmus 		default:
114370d59669SSiarzhuk Zharski 			syslog(LOG_ERR, "Color space unknown. \n");
11449949213aSStephan Aßmus 			return Error(ins, image, NULL, 0, NULL, B_ERROR);
11459949213aSStephan Aßmus 			break;
11469949213aSStephan Aßmus 	}
11479949213aSStephan Aßmus 
11489949213aSStephan Aßmus 	float width = (float)jas_image_width(image);
11499949213aSStephan Aßmus 	float height = (float)jas_image_height(image);
11509949213aSStephan Aßmus 
11519949213aSStephan Aßmus 	// Bytes count in one line of image (scanline)
11529949213aSStephan Aßmus 	int64 out_row_bytes = (int32)width * out_color_components;
11539949213aSStephan Aßmus 		// NOTE: things will go wrong if "out_row_bytes" wouldn't fit into 32 bits
11549949213aSStephan Aßmus 
11559949213aSStephan Aßmus 	// !!! Initialize this bounds rect to the size of your image
11569949213aSStephan Aßmus 	BRect bounds(0, 0, width - 1, height - 1);
11579949213aSStephan Aßmus 
115894a204f0SStephan Aßmus 
11599949213aSStephan Aßmus 	// Fill out the B_TRANSLATOR_BITMAP's header
11609949213aSStephan Aßmus 	TranslatorBitmap header;
11619949213aSStephan Aßmus 	header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP);
11629949213aSStephan Aßmus 	header.bounds.left = B_HOST_TO_BENDIAN_FLOAT(bounds.left);
11639949213aSStephan Aßmus 	header.bounds.top = B_HOST_TO_BENDIAN_FLOAT(bounds.top);
11649949213aSStephan Aßmus 	header.bounds.right = B_HOST_TO_BENDIAN_FLOAT(bounds.right);
11659949213aSStephan Aßmus 	header.bounds.bottom = B_HOST_TO_BENDIAN_FLOAT(bounds.bottom);
11669949213aSStephan Aßmus 	header.colors = (color_space)B_HOST_TO_BENDIAN_INT32(out_color_space);
11679949213aSStephan Aßmus 	header.rowBytes = B_HOST_TO_BENDIAN_INT32(out_row_bytes);
11689949213aSStephan Aßmus 	header.dataSize = B_HOST_TO_BENDIAN_INT32((int32)(out_row_bytes * height));
11699949213aSStephan Aßmus 
11709949213aSStephan Aßmus 	// Write out the header
11719949213aSStephan Aßmus 	status_t err = out->Write(&header, sizeof(TranslatorBitmap));
1172117da2d7SAxel Dörfler 	if (err < B_OK)
1173117da2d7SAxel Dörfler 		return Error(ins, image, NULL, 0, NULL, err);
1174117da2d7SAxel Dörfler 	if (err < (int)sizeof(TranslatorBitmap))
1175117da2d7SAxel Dörfler 		return Error(ins, image, NULL, 0, NULL, B_ERROR);
11769949213aSStephan Aßmus 
11779949213aSStephan Aßmus 	jpr_uchar_t *out_scanline = (jpr_uchar_t*) malloc(out_row_bytes);
1178117da2d7SAxel Dörfler 	if (out_scanline == NULL)
1179117da2d7SAxel Dörfler 		return Error(ins, image, NULL, 0, NULL, B_ERROR);
11809949213aSStephan Aßmus 
11819949213aSStephan Aßmus 	int32 i = 0;
1182117da2d7SAxel Dörfler 	for (i = 0; i < (long)in_color_components; i++) {
11839949213aSStephan Aßmus 		pixels[i] = jas_matrix_create(1, (unsigned int)width);
11849949213aSStephan Aßmus 		if (pixels[i] == (jas_matrix_t *)NULL)
11859949213aSStephan Aßmus 			return Error(ins, image, pixels, i + 1, out_scanline, B_ERROR);
11869949213aSStephan Aßmus 	}
11879949213aSStephan Aßmus 
11889949213aSStephan Aßmus 	int32 y = 0;
1189117da2d7SAxel Dörfler 	for (y = 0; y < (long)height; y++) {
119013eaf8faSStephan Aßmus 		for (i = 0; i < (long)in_color_components; i++) {
119113eaf8faSStephan Aßmus 			(void)jas_image_readcmpt(image, (short)i, 0, (unsigned int)y,
119213eaf8faSStephan Aßmus 				(unsigned int)width, 1, pixels[i]);
119313eaf8faSStephan Aßmus 		}
11949949213aSStephan Aßmus 
11959949213aSStephan Aßmus 		converter(pixels, out_scanline, (int32)width);
11969949213aSStephan Aßmus 
11979949213aSStephan Aßmus 		err = out->Write(out_scanline, out_row_bytes);
119813eaf8faSStephan Aßmus 		if (err < out_row_bytes) {
119994a204f0SStephan Aßmus 			return (err < B_OK) ? Error(ins, image, pixels, in_color_components,
120094a204f0SStephan Aßmus 				out_scanline, err)
120113eaf8faSStephan Aßmus 				: Error(ins, image, pixels, in_color_components, out_scanline,
120213eaf8faSStephan Aßmus 					B_ERROR);
120313eaf8faSStephan Aßmus 		}
12049949213aSStephan Aßmus 	}
12059949213aSStephan Aßmus 
12069949213aSStephan Aßmus 	free(out_scanline);
12079949213aSStephan Aßmus 
12089949213aSStephan Aßmus 	for (i = 0; i < (long)in_color_components; i++)
12099949213aSStephan Aßmus 		jas_matrix_destroy(pixels[i]);
1210117da2d7SAxel Dörfler 
12119949213aSStephan Aßmus 	jas_stream_close(ins);
12129949213aSStephan Aßmus 	jas_image_destroy(image);
12139949213aSStephan Aßmus 	jas_image_clearfmts();
12149949213aSStephan Aßmus 
12159949213aSStephan Aßmus 	return B_OK;
12169949213aSStephan Aßmus }
12179949213aSStephan Aßmus 
1218117da2d7SAxel Dörfler 
121994a204f0SStephan Aßmus /*! searches in both inputFormats & outputFormats */
122094a204f0SStephan Aßmus status_t
122194a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info,
122294a204f0SStephan Aßmus 	uint32 formatType, translator_id id)
122394a204f0SStephan Aßmus {
122494a204f0SStephan Aßmus 	int32 formatCount;
122594a204f0SStephan Aßmus 	const translation_format* formats = OutputFormats(&formatCount);
122694a204f0SStephan Aßmus 
122794a204f0SStephan Aßmus 	for (int i = 0; i <= 1; formats = InputFormats(&formatCount), i++) {
122894a204f0SStephan Aßmus 		if (PopulateInfoFromFormat(info, formatType,
122994a204f0SStephan Aßmus 			formats, formatCount) == B_OK) {
123094a204f0SStephan Aßmus 			info->translator = id;
123194a204f0SStephan Aßmus 			return B_OK;
123294a204f0SStephan Aßmus 		}
123394a204f0SStephan Aßmus 	}
123494a204f0SStephan Aßmus 
123594a204f0SStephan Aßmus 	return B_ERROR;
123694a204f0SStephan Aßmus }
123794a204f0SStephan Aßmus 
123894a204f0SStephan Aßmus 
123994a204f0SStephan Aßmus status_t
124094a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info,
124194a204f0SStephan Aßmus 	uint32 formatType, const translation_format* formats, int32 formatCount)
124294a204f0SStephan Aßmus {
124394a204f0SStephan Aßmus 	for (int i = 0; i < formatCount; i++) {
124494a204f0SStephan Aßmus 		if (formats[i].type == formatType) {
124594a204f0SStephan Aßmus 			info->type = formatType;
124694a204f0SStephan Aßmus 			info->group = formats[i].group;
124794a204f0SStephan Aßmus 			info->quality = formats[i].quality;
124894a204f0SStephan Aßmus 			info->capability = formats[i].capability;
1249c44966dfSJérôme Duval 			if (strncmp(formats[i].name,
1250c44966dfSJérôme Duval 				"Be Bitmap Format (JPEG2000Translator)",
1251c44966dfSJérôme Duval 				sizeof("Be Bitmap Format (JPEG2000Translator)")) == 0)
1252c44966dfSJérôme Duval 				strncpy(info->name,
1253c44966dfSJérôme Duval 					B_TRANSLATE("Be Bitmap Format (JPEG2000Translator)"),
1254c44966dfSJérôme Duval 					sizeof(info->name));
1255c44966dfSJérôme Duval 			else
1256c44966dfSJérôme Duval 				strncpy(info->name, formats[i].name, sizeof(info->name));
1257c44966dfSJérôme Duval 			strncpy(info->MIME,  formats[i].MIME, sizeof(info->MIME));
125894a204f0SStephan Aßmus 			return B_OK;
125994a204f0SStephan Aßmus 		}
126094a204f0SStephan Aßmus 	}
126194a204f0SStephan Aßmus 
126294a204f0SStephan Aßmus 	return B_ERROR;
126394a204f0SStephan Aßmus }
126494a204f0SStephan Aßmus 
126594a204f0SStephan Aßmus 
1266117da2d7SAxel Dörfler /*!
1267117da2d7SAxel Dörfler 	Frees jpeg alocated memory
1268117da2d7SAxel Dörfler 	Returns given error (B_ERROR by default)
1269117da2d7SAxel Dörfler */
12709949213aSStephan Aßmus status_t
127113eaf8faSStephan Aßmus Error(jas_stream_t* stream, jas_image_t* image, jas_matrix_t** pixels,
127213eaf8faSStephan Aßmus 	int32 pixels_count, jpr_uchar_t* scanline, status_t error)
12739949213aSStephan Aßmus {
1274117da2d7SAxel Dörfler 	if (pixels) {
12759949213aSStephan Aßmus 		int32 i;
1276117da2d7SAxel Dörfler 		for (i = 0; i < (long)pixels_count; i++) {
12779949213aSStephan Aßmus 			if (pixels[i] != NULL)
12789949213aSStephan Aßmus 				jas_matrix_destroy(pixels[i]);
12799949213aSStephan Aßmus 		}
1280117da2d7SAxel Dörfler 	}
12819949213aSStephan Aßmus 	if (stream)
12829949213aSStephan Aßmus 		jas_stream_close(stream);
12839949213aSStephan Aßmus 	if (image)
12849949213aSStephan Aßmus 		jas_image_destroy(image);
1285117da2d7SAxel Dörfler 
12869949213aSStephan Aßmus 	jas_image_clearfmts();
12879949213aSStephan Aßmus 	free(scanline);
12889949213aSStephan Aßmus 
12899949213aSStephan Aßmus 	return error;
12909949213aSStephan Aßmus }
1291117da2d7SAxel Dörfler 
1292117da2d7SAxel Dörfler 
1293117da2d7SAxel Dörfler //	#pragma mark -
1294117da2d7SAxel Dörfler 
129594a204f0SStephan Aßmus BTranslator*
129694a204f0SStephan Aßmus make_nth_translator(int32 n, image_id you, uint32 flags, ...)
129794a204f0SStephan Aßmus {
129894a204f0SStephan Aßmus 	if (!n)
129994a204f0SStephan Aßmus 		return new JP2Translator();
130094a204f0SStephan Aßmus 
130194a204f0SStephan Aßmus 	return NULL;
130294a204f0SStephan Aßmus }
130394a204f0SStephan Aßmus 
1304117da2d7SAxel Dörfler 
1305117da2d7SAxel Dörfler int
1306117da2d7SAxel Dörfler main()
1307117da2d7SAxel Dörfler {
1308117da2d7SAxel Dörfler 	BApplication app("application/x-vnd.Haiku-JPEG2000Translator");
130994a204f0SStephan Aßmus 	JP2Translator* translator = new JP2Translator();
131070d59669SSiarzhuk Zharski 	if (LaunchTranslatorWindow(translator, sTranslatorName) == B_OK)
1311117da2d7SAxel Dörfler 		app.Run();
131294a204f0SStephan Aßmus 
1313117da2d7SAxel Dörfler 	return 0;
1314117da2d7SAxel Dörfler }
1315117da2d7SAxel Dörfler 
1316