xref: /haiku/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp (revision 7d48219b470e22b5147f0ae9adc8ee2049c981d3)
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