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