xref: /haiku/src/add-ons/translators/jpeg2000/JPEG2000Translator.cpp (revision 050c34d5d197433dc8cf668f967883864a2f7ec3)
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"
3494a204f0SStephan Aßmus #include "TranslatorWindow.h"
359949213aSStephan Aßmus 
3670d59669SSiarzhuk Zharski #include <syslog.h>
3770d59669SSiarzhuk Zharski 
387d48219bSHannah Boneß #include <LayoutBuilder.h>
39117da2d7SAxel Dörfler #include <TabView.h>
4094a204f0SStephan Aßmus #include <TextView.h>
41117da2d7SAxel Dörfler 
429949213aSStephan Aßmus 
43546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
44546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "JPEG2000Translator"
45c44966dfSJé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 
562e49ff35SSiarzhuk Zharski static int32 sTranslatorVersion = B_TRANSLATION_MAKE_VERSION(1, 0, 0);
572e49ff35SSiarzhuk Zharski 
581da233a7SSiarzhuk Zharski static const char* sTranslatorName = B_TRANSLATE("JPEG2000 images");
591da233a7SSiarzhuk Zharski static const char* sTranslatorInfo = B_TRANSLATE("©2002-2003, Shard\n"
60117da2d7SAxel Dörfler 	"©2005-2006, Haiku\n"
61b0bc48fbSAxel Dörfler 	"\n"
62b0bc48fbSAxel Dörfler 	"Based on JasPer library:\n"
63b0bc48fbSAxel Dörfler 	"© 1999-2000, Image Power, Inc. and\n"
64b0bc48fbSAxel Dörfler 	"the University of British Columbia, Canada.\n"
65b0bc48fbSAxel Dörfler 	"© 2001-2003 Michael David Adams.\n"
662e49ff35SSiarzhuk Zharski 	"\thttp://www.ece.uvic.ca/~mdadams/jasper/\n"
67b0bc48fbSAxel Dörfler 	"\n"
68b0bc48fbSAxel Dörfler 	"ImageMagick's jp2 codec was used as \"tutorial\".\n"
692e49ff35SSiarzhuk Zharski 	"\thttp://www.imagemagick.org/\n");
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 
98fdfe641dSJérôme Duval #define	JP2_BOX_JP		0x6a502020
99fdfe641dSJérôme Duval #define	JPC_MS_SOC		0xff4f
100fdfe641dSJérôme Duval 
101fdfe641dSJérôme Duval 
10294a204f0SStephan Aßmus namespace conversion{
103117da2d7SAxel Dörfler //!	Make RGB32 scanline from *pixels[3]
104117da2d7SAxel Dörfler inline void
read_rgb24_to_rgb32(jas_matrix_t ** pixels,uchar * scanline,int width)105fdfe641dSJérôme Duval read_rgb24_to_rgb32(jas_matrix_t** pixels, uchar* scanline, int width)
106117da2d7SAxel Dörfler {
107117da2d7SAxel Dörfler 	int32 index = 0;
108117da2d7SAxel Dörfler 	int32 x = 0;
109117da2d7SAxel Dörfler 	while (x < width) {
110fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[2], x);
111fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[1], x);
112fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[0], x);
113117da2d7SAxel Dörfler 		scanline[index++] = 255;
114117da2d7SAxel Dörfler 		x++;
115117da2d7SAxel Dörfler 	}
116117da2d7SAxel Dörfler }
117117da2d7SAxel Dörfler 
118117da2d7SAxel Dörfler 
119117da2d7SAxel Dörfler //!	Make gray scanline from *pixels[1]
120117da2d7SAxel Dörfler inline void
read_gray_to_rgb32(jas_matrix_t ** pixels,uchar * scanline,int width)121fdfe641dSJérôme Duval read_gray_to_rgb32(jas_matrix_t** pixels, uchar* scanline, int width)
122117da2d7SAxel Dörfler {
123117da2d7SAxel Dörfler 	int32 index = 0;
124117da2d7SAxel Dörfler 	int32 x = 0;
125fdfe641dSJérôme Duval 	uchar color = 0;
126117da2d7SAxel Dörfler 	while (x < width) {
127fdfe641dSJérôme Duval 		color = (uchar)jas_matrix_getv(pixels[0], x++);
128117da2d7SAxel Dörfler 		scanline[index++] = color;
129117da2d7SAxel Dörfler 		scanline[index++] = color;
130117da2d7SAxel Dörfler 		scanline[index++] = color;
131117da2d7SAxel Dörfler 		scanline[index++] = 255;
132117da2d7SAxel Dörfler 	}
133117da2d7SAxel Dörfler }
134117da2d7SAxel Dörfler 
135117da2d7SAxel Dörfler 
136117da2d7SAxel Dörfler /*!
137117da2d7SAxel Dörfler 	Make RGBA32 scanline from *pixels[4]
138117da2d7SAxel Dörfler 	(just read data to scanline)
139117da2d7SAxel Dörfler */
140117da2d7SAxel Dörfler inline void
read_rgba32(jas_matrix_t ** pixels,uchar * scanline,int width)141fdfe641dSJérôme Duval read_rgba32(jas_matrix_t** pixels, uchar *scanline, int width)
142117da2d7SAxel Dörfler {
143117da2d7SAxel Dörfler 	int32 index = 0;
144117da2d7SAxel Dörfler 	int32 x = 0;
145117da2d7SAxel Dörfler 	while (x < width) {
146fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[2], x);
147fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[1], x);
148fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[0], x);
149fdfe641dSJérôme Duval 		scanline[index++] = (uchar)jas_matrix_getv(pixels[3], x);
150117da2d7SAxel Dörfler 		x++;
151117da2d7SAxel Dörfler 	}
152117da2d7SAxel Dörfler }
153117da2d7SAxel Dörfler 
154117da2d7SAxel Dörfler 
155117da2d7SAxel Dörfler /*!
156117da2d7SAxel Dörfler 	Make gray scanline from *pixels[1]
157117da2d7SAxel Dörfler 	(just read data to scanline)
158117da2d7SAxel Dörfler */
159117da2d7SAxel Dörfler inline void
read_gray(jas_matrix_t ** pixels,uchar * scanline,int width)160fdfe641dSJérôme Duval read_gray(jas_matrix_t** pixels, uchar* scanline, int width)
161117da2d7SAxel Dörfler {
162117da2d7SAxel Dörfler 	int32 x = 0;
163117da2d7SAxel Dörfler 	while (x < width) {
164fdfe641dSJérôme Duval 		scanline[x] = (uchar)jas_matrix_getv(pixels[0], x);
165117da2d7SAxel Dörfler 		x++;
166117da2d7SAxel Dörfler 	}
167117da2d7SAxel Dörfler }
168117da2d7SAxel Dörfler 
169117da2d7SAxel Dörfler 
170117da2d7SAxel Dörfler //!	Make *pixels[1] from gray1 scanline
171117da2d7SAxel Dörfler inline void
write_gray1_to_gray(jas_matrix_t ** pixels,uchar * scanline,int width)172fdfe641dSJérôme Duval write_gray1_to_gray(jas_matrix_t** pixels, uchar* scanline, int width)
173117da2d7SAxel Dörfler {
174117da2d7SAxel Dörfler 	int32 x = 0;
175117da2d7SAxel Dörfler 	int32 index = 0;
176117da2d7SAxel Dörfler 	while (x < (width/8)) {
177117da2d7SAxel Dörfler 		unsigned char c = scanline[x++];
178117da2d7SAxel Dörfler 		for (int b = 128; b; b = b >> 1) {
179117da2d7SAxel Dörfler 			if (c & b)
180117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[0], index++, 0);
181117da2d7SAxel Dörfler 			else
182117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[0], index++, 255);
183117da2d7SAxel Dörfler 		}
184117da2d7SAxel Dörfler 	}
185117da2d7SAxel Dörfler }
186117da2d7SAxel Dörfler 
187117da2d7SAxel Dörfler 
188117da2d7SAxel Dörfler //!	Make *pixels[3] from gray1 scanline
189117da2d7SAxel Dörfler inline void
write_gray1_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)190fdfe641dSJérôme Duval write_gray1_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
191117da2d7SAxel Dörfler {
192117da2d7SAxel Dörfler 	int32 x = 0;
193117da2d7SAxel Dörfler 	int32 index = 0;
194117da2d7SAxel Dörfler 	while (x < (width / 8)) {
195117da2d7SAxel Dörfler 		unsigned char c = scanline[x++];
196117da2d7SAxel Dörfler 		for (int b = 128; b; b = b >> 1) {
197117da2d7SAxel Dörfler 			if (c & b) {
198117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[0], index, 0);
199117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[1], index, 0);
200117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[2], index, 0);
201117da2d7SAxel Dörfler 			} else {
202117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[0], index, 255);
203117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[1], index, 255);
204117da2d7SAxel Dörfler 				jas_matrix_setv(pixels[2], index, 255);
205117da2d7SAxel Dörfler 			}
206117da2d7SAxel Dörfler 			index++;
207117da2d7SAxel Dörfler 		}
208117da2d7SAxel Dörfler 	}
209117da2d7SAxel Dörfler }
210117da2d7SAxel Dörfler 
211117da2d7SAxel Dörfler 
212117da2d7SAxel Dörfler //!	Make *pixels[3] from cmap8 scanline
213117da2d7SAxel Dörfler inline void
write_cmap8_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)214fdfe641dSJérôme Duval write_cmap8_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
215117da2d7SAxel Dörfler {
216117da2d7SAxel Dörfler 	const color_map* map = system_colors();
217117da2d7SAxel Dörfler 	int32 x = 0;
218117da2d7SAxel Dörfler 	while (x < width) {
219117da2d7SAxel Dörfler 		rgb_color color = map->color_list[scanline[x]];
220117da2d7SAxel Dörfler 
221117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, color.red);
222117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, color.green);
223117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, color.blue);
224117da2d7SAxel Dörfler 		x++;
225117da2d7SAxel Dörfler 	}
226117da2d7SAxel Dörfler }
227117da2d7SAxel Dörfler 
228117da2d7SAxel Dörfler 
229117da2d7SAxel Dörfler /*!
230117da2d7SAxel Dörfler 	Make *pixels[1] from gray scanline
231117da2d7SAxel Dörfler 	(just write data to pixels)
232117da2d7SAxel Dörfler */
233117da2d7SAxel Dörfler inline void
write_gray(jas_matrix_t ** pixels,uchar * scanline,int width)234fdfe641dSJérôme Duval write_gray(jas_matrix_t** pixels, uchar* scanline, int width)
235117da2d7SAxel Dörfler {
236117da2d7SAxel Dörfler 	int32 x = 0;
237117da2d7SAxel Dörfler 	while (x < width) {
238117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[x]);
239117da2d7SAxel Dörfler 		x++;
240117da2d7SAxel Dörfler 	}
241117da2d7SAxel Dörfler }
242117da2d7SAxel Dörfler 
243117da2d7SAxel Dörfler 
244117da2d7SAxel Dörfler /*!
245117da2d7SAxel Dörfler 	Make *pixels[3] from RGB15/RGBA15 scanline
246117da2d7SAxel Dörfler 	(just write data to pixels)
247117da2d7SAxel Dörfler */
248117da2d7SAxel Dörfler inline void
write_rgb15_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)249fdfe641dSJérôme Duval write_rgb15_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
250117da2d7SAxel Dörfler {
251117da2d7SAxel Dörfler 	int32 x = 0;
252117da2d7SAxel Dörfler 	int32 index = 0;
253117da2d7SAxel Dörfler 	int16 in_pixel;
254117da2d7SAxel Dörfler 	while (x < width) {
255117da2d7SAxel Dörfler 		in_pixel = scanline[index] | (scanline[index+1] << 8);
256117da2d7SAxel Dörfler 		index += 2;
257117da2d7SAxel Dörfler 
25894a204f0SStephan Aßmus 		jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7)
25994a204f0SStephan Aßmus 			| (((in_pixel & 0x7c00)) >> 12));
26094a204f0SStephan Aßmus 		jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2)
26194a204f0SStephan Aßmus 			| (((in_pixel & 0x3e0)) >> 7));
26294a204f0SStephan Aßmus 		jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
26394a204f0SStephan Aßmus 			| (((in_pixel & 0x1f)) >> 2));
264117da2d7SAxel Dörfler 		x++;
265117da2d7SAxel Dörfler 	}
266117da2d7SAxel Dörfler }
267117da2d7SAxel Dörfler 
268117da2d7SAxel Dörfler 
269117da2d7SAxel Dörfler /*!
270117da2d7SAxel Dörfler 	Make *pixels[3] from RGB15/RGBA15 bigendian scanline
271117da2d7SAxel Dörfler 	(just write data to pixels)
272117da2d7SAxel Dörfler */
273117da2d7SAxel Dörfler inline void
write_rgb15b_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)274fdfe641dSJérôme Duval write_rgb15b_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
275117da2d7SAxel Dörfler {
276117da2d7SAxel Dörfler 	int32 x = 0;
277117da2d7SAxel Dörfler 	int32 index = 0;
278117da2d7SAxel Dörfler 	int16 in_pixel;
279117da2d7SAxel Dörfler 	while (x < width) {
280117da2d7SAxel Dörfler 		in_pixel = scanline[index + 1] | (scanline[index] << 8);
281117da2d7SAxel Dörfler 		index += 2;
282117da2d7SAxel Dörfler 
28394a204f0SStephan Aßmus 		jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7)
28494a204f0SStephan Aßmus 			| (((in_pixel & 0x7c00)) >> 12));
28594a204f0SStephan Aßmus 		jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2)
28694a204f0SStephan Aßmus 			| (((in_pixel & 0x3e0)) >> 7));
28794a204f0SStephan Aßmus 		jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
28894a204f0SStephan Aßmus 			| (((in_pixel & 0x1f)) >> 2));
289117da2d7SAxel Dörfler 		x++;
290117da2d7SAxel Dörfler 	}
291117da2d7SAxel Dörfler }
292117da2d7SAxel Dörfler 
293117da2d7SAxel Dörfler 
294117da2d7SAxel Dörfler /*!
295117da2d7SAxel Dörfler 	Make *pixels[3] from RGB16/RGBA16 scanline
296117da2d7SAxel Dörfler 	(just write data to pixels)
297117da2d7SAxel Dörfler */
298117da2d7SAxel Dörfler inline void
write_rgb16_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)299fdfe641dSJérôme Duval write_rgb16_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
300117da2d7SAxel Dörfler {
301117da2d7SAxel Dörfler 	int32 x = 0;
302117da2d7SAxel Dörfler 	int32 index = 0;
303117da2d7SAxel Dörfler 	int16 in_pixel;
304117da2d7SAxel Dörfler 	while (x < width) {
305117da2d7SAxel Dörfler 		in_pixel = scanline[index] | (scanline[index+1] << 8);
306117da2d7SAxel Dörfler 		index += 2;
307117da2d7SAxel Dörfler 
30894a204f0SStephan Aßmus 		jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8)
30994a204f0SStephan Aßmus 			| (((in_pixel & 0x7c00)) >> 12));
31094a204f0SStephan Aßmus 		jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3)
31194a204f0SStephan Aßmus 			| (((in_pixel & 0x7e0)) >> 9));
31294a204f0SStephan Aßmus 		jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
31394a204f0SStephan Aßmus 			| (((in_pixel & 0x1f)) >> 2));
314117da2d7SAxel Dörfler 		x++;
315117da2d7SAxel Dörfler 	}
316117da2d7SAxel Dörfler }
317117da2d7SAxel Dörfler 
318117da2d7SAxel Dörfler 
319117da2d7SAxel Dörfler /*!
320117da2d7SAxel Dörfler 	Make *pixels[3] from RGB16/RGBA16 bigendian scanline
321117da2d7SAxel Dörfler 	(just write data to pixels)
322117da2d7SAxel Dörfler */
323117da2d7SAxel Dörfler inline void
write_rgb16b_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)324fdfe641dSJérôme Duval write_rgb16b_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
325117da2d7SAxel Dörfler {
326117da2d7SAxel Dörfler 	int32 x = 0;
327117da2d7SAxel Dörfler 	int32 index = 0;
328117da2d7SAxel Dörfler 	int16 in_pixel;
329117da2d7SAxel Dörfler 	while (x < width) {
330117da2d7SAxel Dörfler 		in_pixel = scanline[index + 1] | (scanline[index] << 8);
331117da2d7SAxel Dörfler 		index += 2;
332117da2d7SAxel Dörfler 
33394a204f0SStephan Aßmus 		jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8)
33494a204f0SStephan Aßmus 			| (((in_pixel & 0xf800)) >> 13));
33594a204f0SStephan Aßmus 		jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3)
33694a204f0SStephan Aßmus 			| (((in_pixel & 0x7e0)) >> 9));
33794a204f0SStephan Aßmus 		jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
33894a204f0SStephan Aßmus 			| (((in_pixel & 0x1f)) >> 2));
339117da2d7SAxel Dörfler 		x++;
340117da2d7SAxel Dörfler 	}
341117da2d7SAxel Dörfler }
342117da2d7SAxel Dörfler 
343117da2d7SAxel Dörfler 
344117da2d7SAxel Dörfler /*!
345117da2d7SAxel Dörfler 	Make *pixels[3] from RGB24 scanline
346117da2d7SAxel Dörfler 	(just write data to pixels)
347117da2d7SAxel Dörfler */
348117da2d7SAxel Dörfler inline void
write_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)349fdfe641dSJérôme Duval write_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
350117da2d7SAxel Dörfler {
351117da2d7SAxel Dörfler 	int32 index = 0;
352117da2d7SAxel Dörfler 	int32 x = 0;
353117da2d7SAxel Dörfler 	while (x < width) {
354117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, scanline[index++]);
355117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, scanline[index++]);
356117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[index++]);
357117da2d7SAxel Dörfler 		x++;
358117da2d7SAxel Dörfler 	}
359117da2d7SAxel Dörfler }
360117da2d7SAxel Dörfler 
361117da2d7SAxel Dörfler 
362117da2d7SAxel Dörfler /*!
363117da2d7SAxel Dörfler 	Make *pixels[3] from RGB24 bigendian scanline
364117da2d7SAxel Dörfler 	(just write data to pixels)
365117da2d7SAxel Dörfler */
366117da2d7SAxel Dörfler inline void
write_rgb24b(jas_matrix_t ** pixels,uchar * scanline,int width)367fdfe641dSJérôme Duval write_rgb24b(jas_matrix_t** pixels, uchar* scanline, int width)
368117da2d7SAxel Dörfler {
369117da2d7SAxel Dörfler 	int32 index = 0;
370117da2d7SAxel Dörfler 	int32 x = 0;
371117da2d7SAxel Dörfler 	while (x < width) {
372117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[index++]);
373117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, scanline[index++]);
374117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, scanline[index++]);
375117da2d7SAxel Dörfler 		x++;
376117da2d7SAxel Dörfler 	}
377117da2d7SAxel Dörfler }
378117da2d7SAxel Dörfler 
379117da2d7SAxel Dörfler 
380117da2d7SAxel Dörfler /*!
381117da2d7SAxel Dörfler 	Make *pixels[3] from RGB32 scanline
382117da2d7SAxel Dörfler 	(just write data to pixels)
383117da2d7SAxel Dörfler */
384117da2d7SAxel Dörfler inline void
write_rgb32_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)385fdfe641dSJérôme Duval write_rgb32_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
386117da2d7SAxel Dörfler {
387117da2d7SAxel Dörfler 	int32 index = 0;
388117da2d7SAxel Dörfler 	int32 x = 0;
389117da2d7SAxel Dörfler 	while (x < width) {
390117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, scanline[index++]);
391117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, scanline[index++]);
392117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[index++]);
393117da2d7SAxel Dörfler 		index++;
394117da2d7SAxel Dörfler 		x++;
395117da2d7SAxel Dörfler 	}
396117da2d7SAxel Dörfler }
397117da2d7SAxel Dörfler 
398117da2d7SAxel Dörfler 
399117da2d7SAxel Dörfler /*!
400117da2d7SAxel Dörfler 	Make *pixels[3] from RGB32 bigendian scanline
401117da2d7SAxel Dörfler 	(just write data to pixels)
402117da2d7SAxel Dörfler */
403117da2d7SAxel Dörfler inline void
write_rgb32b_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)404fdfe641dSJérôme Duval write_rgb32b_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
405117da2d7SAxel Dörfler {
406117da2d7SAxel Dörfler 	int32 index = 0;
407117da2d7SAxel Dörfler 	int32 x = 0;
408117da2d7SAxel Dörfler 	while (x < width) {
409117da2d7SAxel Dörfler 		index++;
410117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[index++]);
411117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, scanline[index++]);
412117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, scanline[index++]);
413117da2d7SAxel Dörfler 		x++;
414117da2d7SAxel Dörfler 	}
415117da2d7SAxel Dörfler }
416117da2d7SAxel Dörfler 
417117da2d7SAxel Dörfler 
418117da2d7SAxel Dörfler /*!
419117da2d7SAxel Dörfler 	Make *pixels[4] from RGBA32 scanline
420117da2d7SAxel Dörfler 	(just write data to pixels)
421117da2d7SAxel Dörfler 	!!! UNTESTED !!!
422117da2d7SAxel Dörfler */
423117da2d7SAxel Dörfler inline void
write_rgba32(jas_matrix_t ** pixels,uchar * scanline,int width)424fdfe641dSJérôme Duval write_rgba32(jas_matrix_t** pixels, uchar* scanline, int width)
425117da2d7SAxel Dörfler {
426117da2d7SAxel Dörfler 	int32 index = 0;
427117da2d7SAxel Dörfler 	int32 x = 0;
428117da2d7SAxel Dörfler 	while (x < width) {
429117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[3], x, scanline[index++]);
430117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, scanline[index++]);
431117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, scanline[index++]);
432117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[index++]);
433117da2d7SAxel Dörfler 		x++;
434117da2d7SAxel Dörfler 	}
435117da2d7SAxel Dörfler }
436117da2d7SAxel Dörfler 
437117da2d7SAxel Dörfler 
438117da2d7SAxel Dörfler /*!
439117da2d7SAxel Dörfler 	Make *pixels[4] from RGBA32 bigendian scanline
440117da2d7SAxel Dörfler 	(just write data to pixels)
441117da2d7SAxel Dörfler 	!!! UNTESTED !!!
442117da2d7SAxel Dörfler */
443117da2d7SAxel Dörfler inline void
write_rgba32b(jas_matrix_t ** pixels,uchar * scanline,int width)444fdfe641dSJérôme Duval write_rgba32b(jas_matrix_t** pixels, uchar* scanline, int width)
445117da2d7SAxel Dörfler {
446117da2d7SAxel Dörfler 	int32 index = 0;
447117da2d7SAxel Dörfler 	int32 x = 0;
448cd6365c7SJérôme Duval 	while (x < width) {
449117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[0], x, scanline[index++]);
450117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[1], x, scanline[index++]);
451117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[2], x, scanline[index++]);
452117da2d7SAxel Dörfler 		jas_matrix_setv(pixels[3], x, scanline[index++]);
453117da2d7SAxel Dörfler 		x++;
454117da2d7SAxel Dörfler 	}
455117da2d7SAxel Dörfler }
456117da2d7SAxel Dörfler 
457117da2d7SAxel Dörfler 
45894a204f0SStephan Aßmus }// end namespace conversion
45994a204f0SStephan Aßmus 
46094a204f0SStephan Aßmus 
461117da2d7SAxel Dörfler //	#pragma mark -	jasper I/O
462117da2d7SAxel Dörfler 
463117da2d7SAxel Dörfler 
464*050c34d5SAugustin Cavalier #if __GNUC__ == 2
465*050c34d5SAugustin Cavalier typedef int jasper_length_t;
466*050c34d5SAugustin Cavalier #else
467*050c34d5SAugustin Cavalier typedef unsigned int jasper_length_t;
468*050c34d5SAugustin Cavalier #endif
469*050c34d5SAugustin Cavalier 
470*050c34d5SAugustin Cavalier 
471117da2d7SAxel Dörfler static int
Read(jas_stream_obj_t * object,char * buffer,const jasper_length_t length)472*050c34d5SAugustin Cavalier Read(jas_stream_obj_t* object, char* buffer, const jasper_length_t length)
4739949213aSStephan Aßmus {
4749949213aSStephan Aßmus 	return (*(BPositionIO**)object)->Read(buffer, length);
4759949213aSStephan Aßmus }
4769949213aSStephan Aßmus 
477117da2d7SAxel Dörfler 
478117da2d7SAxel Dörfler static int
Write(jas_stream_obj_t * object,const char * buffer,const jasper_length_t length)479*050c34d5SAugustin Cavalier Write(jas_stream_obj_t* object, const char* buffer, const jasper_length_t length)
4809949213aSStephan Aßmus {
4819949213aSStephan Aßmus 	return (*(BPositionIO**)object)->Write(buffer, length);
4829949213aSStephan Aßmus }
4839949213aSStephan Aßmus 
484117da2d7SAxel Dörfler 
485117da2d7SAxel Dörfler static long
Seek(jas_stream_obj_t * object,long offset,int origin)486117da2d7SAxel Dörfler Seek(jas_stream_obj_t* object, long offset, int origin)
4879949213aSStephan Aßmus {
4889949213aSStephan Aßmus 	return (*(BPositionIO**)object)->Seek(offset, origin);
4899949213aSStephan Aßmus }
4909949213aSStephan Aßmus 
491117da2d7SAxel Dörfler 
492117da2d7SAxel Dörfler static int
Close(jas_stream_obj_t * object)493117da2d7SAxel Dörfler Close(jas_stream_obj_t* object)
4949949213aSStephan Aßmus {
495117da2d7SAxel Dörfler 	return 0;
4969949213aSStephan Aßmus }
4979949213aSStephan Aßmus 
498117da2d7SAxel Dörfler 
499117da2d7SAxel Dörfler static jas_stream_ops_t positionIOops = {
5009949213aSStephan Aßmus 	Read,
5019949213aSStephan Aßmus 	Write,
5029949213aSStephan Aßmus 	Seek,
5039949213aSStephan Aßmus 	Close
5049949213aSStephan Aßmus };
5059949213aSStephan Aßmus 
506117da2d7SAxel Dörfler 
507117da2d7SAxel Dörfler static jas_stream_t*
jas_stream_positionIOopen(BPositionIO * positionIO)508117da2d7SAxel Dörfler jas_stream_positionIOopen(BPositionIO *positionIO)
5099949213aSStephan Aßmus {
5109949213aSStephan Aßmus 	jas_stream_t* stream;
5119949213aSStephan Aßmus 
5129949213aSStephan Aßmus 	stream = (jas_stream_t *)malloc(sizeof(jas_stream_t));
5139949213aSStephan Aßmus 	if (stream == (jas_stream_t *)NULL)
514117da2d7SAxel Dörfler 		return (jas_stream_t *)NULL;
515117da2d7SAxel Dörfler 
516117da2d7SAxel Dörfler 	memset(stream, 0, sizeof(jas_stream_t));
517117da2d7SAxel Dörfler 	stream->rwlimit_ = -1;
5189949213aSStephan Aßmus 	stream->obj_=(jas_stream_obj_t *)malloc(sizeof(BPositionIO*));
51913eaf8faSStephan Aßmus 	if (stream->obj_ == (jas_stream_obj_t *)NULL) {
52013eaf8faSStephan Aßmus 		free(stream);
521117da2d7SAxel Dörfler 		return (jas_stream_t *)NULL;
52213eaf8faSStephan Aßmus 	}
523117da2d7SAxel Dörfler 
5249949213aSStephan Aßmus 	*((BPositionIO**)stream->obj_) = positionIO;
5259949213aSStephan Aßmus 	stream->ops_ = (&positionIOops);
5269949213aSStephan Aßmus 	stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY;
5279949213aSStephan Aßmus 	stream->bufbase_ = stream->tinybuf_;
5289949213aSStephan Aßmus 	stream->bufsize_ = 1;
5299949213aSStephan Aßmus 	stream->bufstart_ = (&stream->bufbase_[JAS_STREAM_MAXPUTBACK]);
5309949213aSStephan Aßmus 	stream->ptr_ = stream->bufstart_;
5319949213aSStephan Aßmus 	stream->bufmode_ |= JAS_STREAM_UNBUF & JAS_STREAM_BUFMODEMASK;
532117da2d7SAxel Dörfler 
533117da2d7SAxel Dörfler 	return stream;
5349949213aSStephan Aßmus }
5359949213aSStephan Aßmus 
5369949213aSStephan Aßmus 
537117da2d7SAxel Dörfler //	#pragma mark -
538117da2d7SAxel Dörfler 
539117da2d7SAxel Dörfler 
SSlider(const char * name,const char * label,BMessage * message,int32 minValue,int32 maxValue,orientation posture,thumb_style thumbType,uint32 flags)54094a204f0SStephan Aßmus SSlider::SSlider(const char* name, const char* label,
541117da2d7SAxel Dörfler 		BMessage* message, int32 minValue, int32 maxValue, orientation posture,
54294a204f0SStephan Aßmus 		thumb_style thumbType, uint32 flags)
54394a204f0SStephan Aßmus 	:
54494a204f0SStephan Aßmus 	BSlider(name, label, message, minValue, maxValue,
54594a204f0SStephan Aßmus 		posture, thumbType, flags)
546117da2d7SAxel Dörfler {
547117da2d7SAxel Dörfler 	rgb_color barColor = { 0, 0, 229, 255 };
548117da2d7SAxel Dörfler 	UseFillColor(true, &barColor);
549117da2d7SAxel Dörfler }
550117da2d7SAxel Dörfler 
551117da2d7SAxel Dörfler 
552117da2d7SAxel Dörfler //!	Update status string - show actual value
5536bda235aSStefano Ceccherini const char*
UpdateText() const5549949213aSStephan Aßmus SSlider::UpdateText() const
5559949213aSStephan Aßmus {
5562b861dd2SAlex Smith 	snprintf(fStatusLabel, sizeof(fStatusLabel), "%" B_PRId32, Value());
557117da2d7SAxel Dörfler 	return fStatusLabel;
5589949213aSStephan Aßmus }
5599949213aSStephan Aßmus 
560117da2d7SAxel Dörfler 
561117da2d7SAxel Dörfler //	#pragma mark -
5629949213aSStephan Aßmus 
563117da2d7SAxel Dörfler 
TranslatorReadView(const char * name,TranslatorSettings * settings)56494a204f0SStephan Aßmus TranslatorReadView::TranslatorReadView(const char* name,
56594a204f0SStephan Aßmus 	TranslatorSettings* settings)
56694a204f0SStephan Aßmus 	:
56794a204f0SStephan Aßmus 	BView(name, 0, new BGroupLayout(B_VERTICAL)),
568117da2d7SAxel Dörfler 	fSettings(settings)
5699949213aSStephan Aßmus {
5702e49ff35SSiarzhuk Zharski 	fGrayAsRGB32 = new BCheckBox("grayasrgb32",
5712e49ff35SSiarzhuk Zharski 		B_TRANSLATE("Read greyscale images as RGB32"),
57294a204f0SStephan Aßmus 		new BMessage(VIEW_MSG_SET_GRAYASRGB32));
57394a204f0SStephan Aßmus 	if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32))
57494a204f0SStephan Aßmus 		fGrayAsRGB32->SetValue(B_CONTROL_ON);
5759949213aSStephan Aßmus 
57694a204f0SStephan Aßmus 	float padding = 10.0f;
5777d48219bSHannah Boneß 	BLayoutBuilder::Group<>(this, B_VERTICAL)
5787d48219bSHannah Boneß 		.SetInsets(padding)
57994a204f0SStephan Aßmus 		.Add(fGrayAsRGB32)
5807d48219bSHannah Boneß 		.AddGlue();
58194a204f0SStephan Aßmus }
58294a204f0SStephan Aßmus 
58394a204f0SStephan Aßmus 
~TranslatorReadView()58494a204f0SStephan Aßmus TranslatorReadView::~TranslatorReadView()
58594a204f0SStephan Aßmus {
58694a204f0SStephan Aßmus 	fSettings->Release();
5879949213aSStephan Aßmus }
5889949213aSStephan Aßmus 
589117da2d7SAxel Dörfler 
5909949213aSStephan Aßmus void
AttachedToWindow()5919949213aSStephan Aßmus TranslatorReadView::AttachedToWindow()
5929949213aSStephan Aßmus {
593117da2d7SAxel Dörfler 	fGrayAsRGB32->SetTarget(this);
5949949213aSStephan Aßmus }
5959949213aSStephan Aßmus 
596117da2d7SAxel Dörfler 
5979949213aSStephan Aßmus void
MessageReceived(BMessage * message)5989949213aSStephan Aßmus TranslatorReadView::MessageReceived(BMessage* message)
5999949213aSStephan Aßmus {
600117da2d7SAxel Dörfler 	switch (message->what) {
6019949213aSStephan Aßmus 		case VIEW_MSG_SET_GRAYASRGB32:
6029949213aSStephan Aßmus 		{
6039949213aSStephan Aßmus 			int32 value;
6049949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
60594a204f0SStephan Aßmus 				bool boolValue = value;
60694a204f0SStephan Aßmus 				fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32, &boolValue);
60794a204f0SStephan Aßmus 				fSettings->SaveSettings();
6089949213aSStephan Aßmus 			}
6099949213aSStephan Aßmus 			break;
6109949213aSStephan Aßmus 		}
6119949213aSStephan Aßmus 		default:
6129949213aSStephan Aßmus 			BView::MessageReceived(message);
6139949213aSStephan Aßmus 			break;
6149949213aSStephan Aßmus 	}
6159949213aSStephan Aßmus }
6169949213aSStephan Aßmus 
6179949213aSStephan Aßmus 
618117da2d7SAxel Dörfler //	#pragma mark - TranslatorWriteView
6199949213aSStephan Aßmus 
620117da2d7SAxel Dörfler 
TranslatorWriteView(const char * name,TranslatorSettings * settings)62194a204f0SStephan Aßmus TranslatorWriteView::TranslatorWriteView(const char* name,
62294a204f0SStephan Aßmus 	TranslatorSettings* settings)
62394a204f0SStephan Aßmus 	:
62494a204f0SStephan Aßmus 	BView(name, 0, new BGroupLayout(B_VERTICAL)),
625117da2d7SAxel Dörfler 	fSettings(settings)
6269949213aSStephan Aßmus {
6272e49ff35SSiarzhuk Zharski 	fQualitySlider = new SSlider("quality", B_TRANSLATE("Output quality"),
62894a204f0SStephan Aßmus 		new BMessage(VIEW_MSG_SET_QUALITY), 0, 100);
629117da2d7SAxel Dörfler 	fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
630117da2d7SAxel Dörfler 	fQualitySlider->SetHashMarkCount(10);
631c44966dfSJérôme Duval 	fQualitySlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High"));
63294a204f0SStephan Aßmus 	fQualitySlider->SetValue(fSettings->SetGetInt32(JP2_SET_QUALITY));
6339949213aSStephan Aßmus 
6342e49ff35SSiarzhuk Zharski 	fGrayAsRGB24 = new BCheckBox("gray1asrgb24",
6352e49ff35SSiarzhuk Zharski 		B_TRANSLATE("Write black-and-white images as RGB24"),
636117da2d7SAxel Dörfler 		new BMessage(VIEW_MSG_SET_GRAY1ASRGB24));
63794a204f0SStephan Aßmus 	if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24))
63894a204f0SStephan Aßmus 		fGrayAsRGB24->SetValue(B_CONTROL_ON);
6399949213aSStephan Aßmus 
6402e49ff35SSiarzhuk Zharski 	fCodeStreamOnly = new BCheckBox("codestreamonly",
6412e49ff35SSiarzhuk Zharski 		B_TRANSLATE("Output only codestream (.jpc)"),
64294a204f0SStephan Aßmus 		new BMessage(VIEW_MSG_SET_JPC));
64394a204f0SStephan Aßmus 	if (fSettings->SetGetBool(JP2_SET_JPC))
64494a204f0SStephan Aßmus 		fCodeStreamOnly->SetValue(B_CONTROL_ON);
6459949213aSStephan Aßmus 
646d9c440a5SJanus 	BLayoutBuilder::Group<>(this, B_VERTICAL)
647d9c440a5SJanus 		.SetInsets(B_USE_DEFAULT_SPACING)
64894a204f0SStephan Aßmus 		.Add(fQualitySlider)
64994a204f0SStephan Aßmus 		.Add(fGrayAsRGB24)
65094a204f0SStephan Aßmus 		.Add(fCodeStreamOnly)
6517d48219bSHannah Boneß 		.AddGlue();
65294a204f0SStephan Aßmus }
653bdaaeb0cSStefano Ceccherini 
6549949213aSStephan Aßmus 
~TranslatorWriteView()65594a204f0SStephan Aßmus TranslatorWriteView::~TranslatorWriteView()
65694a204f0SStephan Aßmus {
65794a204f0SStephan Aßmus 	fSettings->Release();
6589949213aSStephan Aßmus }
6599949213aSStephan Aßmus 
660117da2d7SAxel Dörfler 
6619949213aSStephan Aßmus void
AttachedToWindow()6629949213aSStephan Aßmus TranslatorWriteView::AttachedToWindow()
6639949213aSStephan Aßmus {
664117da2d7SAxel Dörfler 	fQualitySlider->SetTarget(this);
665117da2d7SAxel Dörfler 	fGrayAsRGB24->SetTarget(this);
666117da2d7SAxel Dörfler 	fCodeStreamOnly->SetTarget(this);
6679949213aSStephan Aßmus }
6689949213aSStephan Aßmus 
669117da2d7SAxel Dörfler 
6709949213aSStephan Aßmus void
MessageReceived(BMessage * message)6719949213aSStephan Aßmus TranslatorWriteView::MessageReceived(BMessage* message)
6729949213aSStephan Aßmus {
673117da2d7SAxel Dörfler 	switch (message->what) {
6749949213aSStephan Aßmus 		case VIEW_MSG_SET_QUALITY:
6759949213aSStephan Aßmus 		{
6769949213aSStephan Aßmus 			int32 value;
6779949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
67894a204f0SStephan Aßmus 				fSettings->SetGetInt32(JP2_SET_QUALITY, &value);
67994a204f0SStephan Aßmus 				fSettings->SaveSettings();
6809949213aSStephan Aßmus 			}
6819949213aSStephan Aßmus 			break;
6829949213aSStephan Aßmus 		}
6839949213aSStephan Aßmus 		case VIEW_MSG_SET_GRAY1ASRGB24:
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_GRAY1_AS_B_RGB24, &boolValue);
68994a204f0SStephan Aßmus 				fSettings->SaveSettings();
6909949213aSStephan Aßmus 			}
6919949213aSStephan Aßmus 			break;
6929949213aSStephan Aßmus 		}
6939949213aSStephan Aßmus 		case VIEW_MSG_SET_JPC:
6949949213aSStephan Aßmus 		{
6959949213aSStephan Aßmus 			int32 value;
6969949213aSStephan Aßmus 			if (message->FindInt32("be:value", &value) == B_OK) {
69794a204f0SStephan Aßmus 				bool boolValue = value;
69894a204f0SStephan Aßmus 				fSettings->SetGetBool(JP2_SET_JPC, &boolValue);
69994a204f0SStephan Aßmus 				fSettings->SaveSettings();
7009949213aSStephan Aßmus 			}
7019949213aSStephan Aßmus 			break;
7029949213aSStephan Aßmus 		}
7039949213aSStephan Aßmus 		default:
7049949213aSStephan Aßmus 			BView::MessageReceived(message);
7059949213aSStephan Aßmus 			break;
7069949213aSStephan Aßmus 	}
7079949213aSStephan Aßmus }
7089949213aSStephan Aßmus 
7099949213aSStephan Aßmus 
710117da2d7SAxel Dörfler //	#pragma mark -
7119949213aSStephan Aßmus 
712117da2d7SAxel Dörfler 
TranslatorAboutView(const char * name)71394a204f0SStephan Aßmus TranslatorAboutView::TranslatorAboutView(const char* name)
71494a204f0SStephan Aßmus 	:
71594a204f0SStephan Aßmus 	BView(name, 0, new BGroupLayout(B_VERTICAL))
7169949213aSStephan Aßmus {
71794a204f0SStephan Aßmus 	BAlignment labelAlignment = BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
7182e49ff35SSiarzhuk Zharski 	BStringView* title = new BStringView("Title", sTranslatorName);
7199949213aSStephan Aßmus 	title->SetFont(be_bold_font);
72094a204f0SStephan Aßmus 	title->SetExplicitAlignment(labelAlignment);
7219949213aSStephan Aßmus 
7223292b902SHumdinger 	char versionString[100];
7233292b902SHumdinger 	snprintf(versionString, sizeof(versionString),
7243292b902SHumdinger 		B_TRANSLATE("Version %d.%d.%d"),
725c44966dfSJérôme Duval 		static_cast<int>(sTranslatorVersion >> 8),
726c44966dfSJérôme Duval 		static_cast<int>((sTranslatorVersion >> 4) & 0xf),
727c44966dfSJérôme Duval 		static_cast<int>(sTranslatorVersion & 0xf));
7289949213aSStephan Aßmus 
72994a204f0SStephan Aßmus 	BStringView* version = new BStringView("Version", versionString);
73094a204f0SStephan Aßmus 	version->SetExplicitAlignment(labelAlignment);
7319949213aSStephan Aßmus 
73294a204f0SStephan Aßmus 	BTextView* infoView = new BTextView("info");
7332e49ff35SSiarzhuk Zharski 	infoView->SetText(sTranslatorInfo);
734f0650dc9Slooncraz 	infoView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
7355f61e00aSDale Cieslak 	rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
7365f61e00aSDale Cieslak 	infoView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
73794a204f0SStephan Aßmus 	infoView->MakeEditable(false);
7389949213aSStephan Aßmus 
739d9c440a5SJanus 	BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
740d9c440a5SJanus 		.SetInsets(B_USE_DEFAULT_SPACING)
74194a204f0SStephan Aßmus 		.Add(title)
74294a204f0SStephan Aßmus 		.Add(version)
7437d48219bSHannah Boneß 		.Add(infoView);
7449949213aSStephan Aßmus }
7459949213aSStephan Aßmus 
7469949213aSStephan Aßmus 
747117da2d7SAxel Dörfler //	#pragma mark -
7489949213aSStephan Aßmus 
749117da2d7SAxel Dörfler 
TranslatorView(const char * name,TranslatorSettings * settings)75094a204f0SStephan Aßmus TranslatorView::TranslatorView(const char* name, TranslatorSettings* settings)
75194a204f0SStephan Aßmus 	:
752d9c440a5SJanus 	BTabView(name, B_WIDTH_FROM_LABEL)
7539949213aSStephan Aßmus {
754d9c440a5SJanus 	SetBorder(B_NO_BORDER);
755d9c440a5SJanus 
756c44966dfSJérôme Duval 	AddTab(new TranslatorWriteView(B_TRANSLATE("Write"),
757c44966dfSJérôme Duval 		settings->Acquire()));
758c44966dfSJérôme Duval 	AddTab(new TranslatorReadView(B_TRANSLATE("Read"),
759c44966dfSJérôme Duval 		settings->Acquire()));
760c44966dfSJérôme Duval 	AddTab(new TranslatorAboutView(B_TRANSLATE("About")));
7619949213aSStephan Aßmus 
76294a204f0SStephan Aßmus 	settings->Release();
7639949213aSStephan Aßmus }
7649949213aSStephan Aßmus 
7659949213aSStephan Aßmus 
766117da2d7SAxel Dörfler //	#pragma mark -
7679949213aSStephan Aßmus 
76894a204f0SStephan Aßmus BView*
NewConfigView(TranslatorSettings * settings)76994a204f0SStephan Aßmus JP2Translator::NewConfigView(TranslatorSettings* settings)
7709949213aSStephan Aßmus {
77194a204f0SStephan Aßmus 	BView* outView = new TranslatorView("TranslatorView", settings);
77294a204f0SStephan Aßmus 	return outView;
7739949213aSStephan Aßmus }
7749949213aSStephan Aßmus 
7759949213aSStephan Aßmus 
JP2Translator()77694a204f0SStephan Aßmus JP2Translator::JP2Translator()
777bf243977SPhilippe Houdoin 	: BaseTranslator(sTranslatorName, sTranslatorInfo, sTranslatorVersion,
778bf243977SPhilippe Houdoin 		sInputFormats, kNumInputFormats,
779bf243977SPhilippe Houdoin 		sOutputFormats, kNumOutputFormats,
780bf243977SPhilippe Houdoin 		JP2_SETTINGS_FILE,
781bf243977SPhilippe Houdoin 		sDefaultSettings, kNumDefaultSettings,
782bf243977SPhilippe Houdoin 		B_TRANSLATOR_BITMAP, JP2_FORMAT)
7839949213aSStephan Aßmus {
7849949213aSStephan Aßmus }
7859949213aSStephan Aßmus 
786117da2d7SAxel Dörfler 
787117da2d7SAxel Dörfler //!	Determine whether or not we can handle this data
7889949213aSStephan Aßmus status_t
DerivedIdentify(BPositionIO * inSource,const translation_format * inFormat,BMessage * ioExtension,translator_info * outInfo,uint32 outType)78994a204f0SStephan Aßmus JP2Translator::DerivedIdentify(BPositionIO* inSource,
79094a204f0SStephan Aßmus 	const translation_format* inFormat, BMessage* ioExtension,
79194a204f0SStephan Aßmus 	translator_info* outInfo, uint32 outType)
7929949213aSStephan Aßmus {
79313eaf8faSStephan Aßmus 	if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP)
79413eaf8faSStephan Aßmus 		&& outType != JP2_FORMAT)
7959949213aSStephan Aßmus 		return B_NO_TRANSLATOR;
7969949213aSStephan Aßmus 
79713eaf8faSStephan Aßmus 	// !!! You might need to make this buffer bigger to test for your
79813eaf8faSStephan Aßmus 	// native format
7999949213aSStephan Aßmus 	off_t position = inSource->Position();
8009949213aSStephan Aßmus 	uint8 header[sizeof(TranslatorBitmap)];
8019949213aSStephan Aßmus 	status_t err = inSource->Read(header, sizeof(TranslatorBitmap));
8029949213aSStephan Aßmus 	inSource->Seek(position, SEEK_SET);
803117da2d7SAxel Dörfler 	if (err < B_OK)
804117da2d7SAxel Dörfler 		return err;
8059949213aSStephan Aßmus 
80613eaf8faSStephan Aßmus 	if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic)
80713eaf8faSStephan Aßmus 		== B_TRANSLATOR_BITMAP) {
80894a204f0SStephan Aßmus 		if (PopulateInfoFromFormat(outInfo, B_TRANSLATOR_BITMAP) != B_OK)
80994a204f0SStephan Aßmus 			return B_NO_TRANSLATOR;
8109949213aSStephan Aßmus 	} else {
81113eaf8faSStephan Aßmus 		if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8)
81213eaf8faSStephan Aßmus 			| header[7]) == JP2_BOX_JP) // JP2
81313eaf8faSStephan Aßmus 			|| (header[0] == (JPC_MS_SOC >> 8) && header[1]
81413eaf8faSStephan Aßmus 			== (JPC_MS_SOC & 0xff)))	// JPC
8159949213aSStephan Aßmus 		{
81694a204f0SStephan Aßmus 			if (PopulateInfoFromFormat(outInfo, JP2_FORMAT) != B_OK)
81794a204f0SStephan Aßmus 				return B_NO_TRANSLATOR;
8189949213aSStephan Aßmus 		} else
8199949213aSStephan Aßmus 			return B_NO_TRANSLATOR;
8209949213aSStephan Aßmus 	}
8219949213aSStephan Aßmus 
8229949213aSStephan Aßmus 	return B_OK;
8239949213aSStephan Aßmus }
8249949213aSStephan Aßmus 
825117da2d7SAxel Dörfler 
8269949213aSStephan Aßmus status_t
DerivedTranslate(BPositionIO * inSource,const translator_info * inInfo,BMessage * ioExtension,uint32 outType,BPositionIO * outDestination,int32 baseType)82794a204f0SStephan Aßmus JP2Translator::DerivedTranslate(BPositionIO* inSource,
82894a204f0SStephan Aßmus 	const translator_info* inInfo, BMessage* ioExtension, uint32 outType,
82994a204f0SStephan Aßmus 	BPositionIO* outDestination, int32 baseType)
8309949213aSStephan Aßmus {
8319949213aSStephan Aßmus 	// If no specific type was requested, convert to the interchange format
832117da2d7SAxel Dörfler 	if (outType == 0)
833117da2d7SAxel Dörfler 		outType = B_TRANSLATOR_BITMAP;
8349949213aSStephan Aßmus 
8359949213aSStephan Aßmus 	// What action to take, based on the findings of Identify()
836117da2d7SAxel Dörfler 	if (outType == inInfo->type)
8379949213aSStephan Aßmus 		return Copy(inSource, outDestination);
838117da2d7SAxel Dörfler 	if (inInfo->type == B_TRANSLATOR_BITMAP && outType == JP2_FORMAT)
8399949213aSStephan Aßmus 		return Compress(inSource, outDestination);
840117da2d7SAxel Dörfler 	if (inInfo->type == JP2_FORMAT && outType == B_TRANSLATOR_BITMAP)
8419949213aSStephan Aßmus 		return Decompress(inSource, outDestination);
8429949213aSStephan Aßmus 
8439949213aSStephan Aßmus 	return B_NO_TRANSLATOR;
8449949213aSStephan Aßmus }
8459949213aSStephan Aßmus 
846117da2d7SAxel Dörfler 
847117da2d7SAxel Dörfler //!	The user has requested the same format for input and output, so just copy
8489949213aSStephan Aßmus status_t
Copy(BPositionIO * in,BPositionIO * out)84994a204f0SStephan Aßmus JP2Translator::Copy(BPositionIO* in, BPositionIO* out)
8509949213aSStephan Aßmus {
8519949213aSStephan Aßmus 	int block_size = 65536;
8529949213aSStephan Aßmus 	void* buffer = malloc(block_size);
8539949213aSStephan Aßmus 	char temp[1024];
8549949213aSStephan Aßmus 	if (buffer == NULL) {
8559949213aSStephan Aßmus 		buffer = temp;
8569949213aSStephan Aßmus 		block_size = 1024;
8579949213aSStephan Aßmus 	}
8589949213aSStephan Aßmus 	status_t err = B_OK;
8599949213aSStephan Aßmus 
8609949213aSStephan Aßmus 	// Read until end of file or error
8619949213aSStephan Aßmus 	while (1) {
8629949213aSStephan Aßmus 		ssize_t to_read = block_size;
8639949213aSStephan Aßmus 		err = in->Read(buffer, to_read);
8649949213aSStephan Aßmus 		// Explicit check for EOF
8659949213aSStephan Aßmus 		if (err == -1) {
866117da2d7SAxel Dörfler 			if (buffer != temp)
867117da2d7SAxel Dörfler 				free(buffer);
8689949213aSStephan Aßmus 			return B_OK;
8699949213aSStephan Aßmus 		}
8709949213aSStephan Aßmus 		if (err <= B_OK) break;
8719949213aSStephan Aßmus 		to_read = err;
8729949213aSStephan Aßmus 		err = out->Write(buffer, to_read);
8739949213aSStephan Aßmus 		if (err != to_read) if (err >= 0) err = B_DEVICE_FULL;
8749949213aSStephan Aßmus 		if (err < B_OK) break;
8759949213aSStephan Aßmus 	}
8769949213aSStephan Aßmus 
877117da2d7SAxel Dörfler 	if (buffer != temp)
878117da2d7SAxel Dörfler 		free(buffer);
8799949213aSStephan Aßmus 	return (err >= 0) ? B_OK : err;
8809949213aSStephan Aßmus }
8819949213aSStephan Aßmus 
882117da2d7SAxel Dörfler 
883117da2d7SAxel Dörfler //!	Encode into the native format
8849949213aSStephan Aßmus status_t
Compress(BPositionIO * in,BPositionIO * out)88594a204f0SStephan Aßmus JP2Translator::Compress(BPositionIO* in, BPositionIO* out)
8869949213aSStephan Aßmus {
88794a204f0SStephan Aßmus 	using namespace conversion;
8889949213aSStephan Aßmus 
8899949213aSStephan Aßmus 	// Read info about bitmap
8909949213aSStephan Aßmus 	TranslatorBitmap header;
8919949213aSStephan Aßmus 	status_t err = in->Read(&header, sizeof(TranslatorBitmap));
892117da2d7SAxel Dörfler 	if (err < B_OK)
893117da2d7SAxel Dörfler 		return err;
894117da2d7SAxel Dörfler 	if (err < (int)sizeof(TranslatorBitmap))
895117da2d7SAxel Dörfler 		return B_ERROR;
8969949213aSStephan Aßmus 
8979949213aSStephan Aßmus 	// Grab dimension, color space, and size information from the stream
8989949213aSStephan Aßmus 	BRect bounds;
8999949213aSStephan Aßmus 	bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left);
9009949213aSStephan Aßmus 	bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top);
9019949213aSStephan Aßmus 	bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right);
9029949213aSStephan Aßmus 	bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
9039949213aSStephan Aßmus 
9049949213aSStephan Aßmus 	int32 in_row_bytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
9059949213aSStephan Aßmus 
9069949213aSStephan Aßmus 	int width = bounds.IntegerWidth() + 1;
9079949213aSStephan Aßmus 	int height = bounds.IntegerHeight() + 1;
9089949213aSStephan Aßmus 
9099949213aSStephan Aßmus 	// Function pointer to write function
9109949213aSStephan Aßmus 	// It MUST point to proper function
911fdfe641dSJérôme Duval 	void (*converter)(jas_matrix_t** pixels, uchar* inscanline,
91213eaf8faSStephan Aßmus 		int width) = write_rgba32;
9139949213aSStephan Aßmus 
9149949213aSStephan Aßmus 	// Default color info
915fdfe641dSJérôme Duval 	int out_color_space = JAS_CLRSPC_SRGB;
9169949213aSStephan Aßmus 	int out_color_components = 3;
9179949213aSStephan Aßmus 
918117da2d7SAxel Dörfler 	switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) {
9199949213aSStephan Aßmus 		case B_GRAY1:
92094a204f0SStephan Aßmus 			if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) {
9219949213aSStephan Aßmus 				converter = write_gray1_to_rgb24;
9229949213aSStephan Aßmus 			} else {
9239949213aSStephan Aßmus 				out_color_components = 1;
924fdfe641dSJérôme Duval 				out_color_space = JAS_CLRSPC_SGRAY;
9259949213aSStephan Aßmus 				converter = write_gray1_to_gray;
9269949213aSStephan Aßmus 			}
9279949213aSStephan Aßmus 			break;
928117da2d7SAxel Dörfler 
9299949213aSStephan Aßmus 		case B_CMAP8:
9309949213aSStephan Aßmus 			converter = write_cmap8_to_rgb24;
9319949213aSStephan Aßmus 			break;
932117da2d7SAxel Dörfler 
9339949213aSStephan Aßmus 		case B_GRAY8:
9349949213aSStephan Aßmus 			out_color_components = 1;
935fdfe641dSJérôme Duval 			out_color_space = JAS_CLRSPC_SGRAY;
9369949213aSStephan Aßmus 			converter = write_gray;
9379949213aSStephan Aßmus 			break;
938117da2d7SAxel Dörfler 
9399949213aSStephan Aßmus 		case B_RGB15:
9409949213aSStephan Aßmus 		case B_RGBA15:
9419949213aSStephan Aßmus 			converter = write_rgb15_to_rgb24;
9429949213aSStephan Aßmus 			break;
943117da2d7SAxel Dörfler 
9449949213aSStephan Aßmus 		case B_RGB15_BIG:
9459949213aSStephan Aßmus 		case B_RGBA15_BIG:
9469949213aSStephan Aßmus 			converter = write_rgb15b_to_rgb24;
9479949213aSStephan Aßmus 			break;
948117da2d7SAxel Dörfler 
9499949213aSStephan Aßmus 		case B_RGB16:
9509949213aSStephan Aßmus 			converter = write_rgb16_to_rgb24;
9519949213aSStephan Aßmus 			break;
952117da2d7SAxel Dörfler 
9539949213aSStephan Aßmus 		case B_RGB16_BIG:
9549949213aSStephan Aßmus 			converter = write_rgb16b_to_rgb24;
9559949213aSStephan Aßmus 			break;
956117da2d7SAxel Dörfler 
9579949213aSStephan Aßmus 		case B_RGB24:
9589949213aSStephan Aßmus 			converter = write_rgb24;
9599949213aSStephan Aßmus 			break;
960117da2d7SAxel Dörfler 
9619949213aSStephan Aßmus 		case B_RGB24_BIG:
9629949213aSStephan Aßmus 			converter = write_rgb24b;
9639949213aSStephan Aßmus 			break;
964117da2d7SAxel Dörfler 
9659949213aSStephan Aßmus 		case B_RGB32:
9669949213aSStephan Aßmus 			converter = write_rgb32_to_rgb24;
9679949213aSStephan Aßmus 			break;
968117da2d7SAxel Dörfler 
9699949213aSStephan Aßmus 		case B_RGB32_BIG:
9709949213aSStephan Aßmus 			converter = write_rgb32b_to_rgb24;
9719949213aSStephan Aßmus 			break;
972117da2d7SAxel Dörfler 
9739949213aSStephan Aßmus 		case B_RGBA32:
9749949213aSStephan Aßmus 		/*
9759949213aSStephan Aßmus 			// In theory it should be possible to write 4 color components
9769949213aSStephan Aßmus 			// to jp2, so it should be possible to have transparency.
9779949213aSStephan Aßmus 			// Unfortunetly libjasper does not agree with that
9789949213aSStephan Aßmus 			// For now i don't know how to modify it :(
9799949213aSStephan Aßmus 
9809949213aSStephan Aßmus 			out_color_components = 4;
9819949213aSStephan Aßmus 			converter = write_rgba32;
9829949213aSStephan Aßmus 		*/
9839949213aSStephan Aßmus 			converter = write_rgb32_to_rgb24;
9849949213aSStephan Aßmus 			break;
985117da2d7SAxel Dörfler 
9869949213aSStephan Aßmus 		case B_RGBA32_BIG:
9879949213aSStephan Aßmus 		/*
9889949213aSStephan Aßmus 			// In theory it should be possible to write 4 color components
9899949213aSStephan Aßmus 			// to jp2, so it should be possible to have transparency.
9909949213aSStephan Aßmus 			// Unfortunetly libjasper does not agree with that
9919949213aSStephan Aßmus 			// For now i don't know how to modify it :(
9929949213aSStephan Aßmus 
9939949213aSStephan Aßmus 			out_color_components = 4;
9949949213aSStephan Aßmus 			converter = write_rgba32b;
9959949213aSStephan Aßmus 		*/
9969949213aSStephan Aßmus 			converter = write_rgb32b_to_rgb24;
9979949213aSStephan Aßmus 			break;
998117da2d7SAxel Dörfler 
9999949213aSStephan Aßmus 		default:
100070d59669SSiarzhuk Zharski 			syslog(LOG_ERR, "Unknown color space.\n");
10019949213aSStephan Aßmus 			return B_ERROR;
10029949213aSStephan Aßmus 	}
10039949213aSStephan Aßmus 
10049949213aSStephan Aßmus 	jas_image_t* image;
10059949213aSStephan Aßmus 	jas_stream_t* outs;
10069949213aSStephan Aßmus 	jas_matrix_t* pixels[4];
10079949213aSStephan Aßmus 	jas_image_cmptparm_t component_info[4];
10089949213aSStephan Aßmus 
10099949213aSStephan Aßmus 	if (jas_init())
10109949213aSStephan Aßmus 		return B_ERROR;
10119949213aSStephan Aßmus 
10129949213aSStephan Aßmus 	if (!(outs = jas_stream_positionIOopen(out)))
10139949213aSStephan Aßmus 		return B_ERROR;
10149949213aSStephan Aßmus 
10159949213aSStephan Aßmus 	int32 i = 0;
1016117da2d7SAxel Dörfler 	for (i = 0; i < (long)out_color_components; i++) {
10179949213aSStephan Aßmus 		(void) memset(component_info + i, 0, sizeof(jas_image_cmptparm_t));
10189949213aSStephan Aßmus 		component_info[i].hstep = 1;
10199949213aSStephan Aßmus 		component_info[i].vstep = 1;
10209949213aSStephan Aßmus 		component_info[i].width = (unsigned int)width;
10219949213aSStephan Aßmus 		component_info[i].height = (unsigned int)height;
10229949213aSStephan Aßmus 		component_info[i].prec = (unsigned int)8;
10239949213aSStephan Aßmus 	}
10249949213aSStephan Aßmus 
102513eaf8faSStephan Aßmus 	image = jas_image_create((short)out_color_components, component_info,
102613eaf8faSStephan Aßmus 		out_color_space);
10279949213aSStephan Aßmus 	if (image == (jas_image_t *)NULL)
10289949213aSStephan Aßmus 		return Error(outs, NULL, NULL, 0, NULL, B_ERROR);
10299949213aSStephan Aßmus 
1030fdfe641dSJérôme Duval 	uchar *in_scanline = (uchar*) malloc(in_row_bytes);
1031117da2d7SAxel Dörfler 	if (in_scanline == NULL)
1032117da2d7SAxel Dörfler 		return Error(outs, image, NULL, 0, NULL, B_ERROR);
10339949213aSStephan Aßmus 
1034117da2d7SAxel Dörfler 	for (i = 0; i < (long)out_color_components; i++) {
10359949213aSStephan Aßmus 		pixels[i] = jas_matrix_create(1, (unsigned int)width);
10369949213aSStephan Aßmus 		if (pixels[i] == (jas_matrix_t *)NULL)
10379949213aSStephan Aßmus 			return Error(outs, image, pixels, i+1, in_scanline, B_ERROR);
10389949213aSStephan Aßmus 	}
10399949213aSStephan Aßmus 
10409949213aSStephan Aßmus 	int32 y = 0;
1041117da2d7SAxel Dörfler 	for (y = 0; y < (long)height; y++) {
10429949213aSStephan Aßmus 		err = in->Read(in_scanline, in_row_bytes);
104313eaf8faSStephan Aßmus 		if (err < in_row_bytes) {
104494a204f0SStephan Aßmus 			return (err < B_OK) ? Error(outs, image, pixels,
104594a204f0SStephan Aßmus 					out_color_components, in_scanline, err)
104613eaf8faSStephan Aßmus 				: Error(outs, image, pixels, out_color_components, in_scanline,
104713eaf8faSStephan Aßmus 					B_ERROR);
104813eaf8faSStephan Aßmus 		}
10499949213aSStephan Aßmus 
10509949213aSStephan Aßmus 		converter(pixels, in_scanline, width);
10519949213aSStephan Aßmus 
105213eaf8faSStephan Aßmus 		for (i = 0; i < (long)out_color_components; i++) {
105313eaf8faSStephan Aßmus 			(void)jas_image_writecmpt(image, (short)i, 0, (unsigned int)y,
105413eaf8faSStephan Aßmus 				(unsigned int)width, 1, pixels[i]);
105513eaf8faSStephan Aßmus 		}
10569949213aSStephan Aßmus 	}
10579949213aSStephan Aßmus 
10589949213aSStephan Aßmus 	char opts[16];
105994a204f0SStephan Aßmus 	sprintf(opts, "rate=%1f",
106094a204f0SStephan Aßmus 		(float)fSettings->SetGetInt32(JP2_SET_QUALITY) / 100.0);
106194a204f0SStephan Aßmus 
106294a204f0SStephan Aßmus 	if (jas_image_encode(image, outs, jas_image_strtofmt(
106394a204f0SStephan Aßmus 			fSettings->SetGetBool(JP2_SET_JPC) ?
106413eaf8faSStephan Aßmus 				(char*)"jpc" : (char*)"jp2"), opts)) {
106594a204f0SStephan Aßmus 		return Error(outs, image, pixels,
106694a204f0SStephan Aßmus 			out_color_components, in_scanline, err);
106713eaf8faSStephan Aßmus 	}
10689949213aSStephan Aßmus 
10699949213aSStephan Aßmus 	free(in_scanline);
10709949213aSStephan Aßmus 
10719949213aSStephan Aßmus 	for (i = 0; i < (long)out_color_components; i++)
10729949213aSStephan Aßmus 		jas_matrix_destroy(pixels[i]);
1073117da2d7SAxel Dörfler 
10749949213aSStephan Aßmus 	jas_stream_close(outs);
10759949213aSStephan Aßmus 	jas_image_destroy(image);
10769949213aSStephan Aßmus 	jas_image_clearfmts();
10779949213aSStephan Aßmus 
10789949213aSStephan Aßmus 	return B_OK;
10799949213aSStephan Aßmus }
10809949213aSStephan Aßmus 
1081117da2d7SAxel Dörfler 
1082117da2d7SAxel Dörfler //!	Decode the native format
10839949213aSStephan Aßmus status_t
Decompress(BPositionIO * in,BPositionIO * out)108494a204f0SStephan Aßmus JP2Translator::Decompress(BPositionIO* in, BPositionIO* out)
10859949213aSStephan Aßmus {
108694a204f0SStephan Aßmus 	using namespace conversion;
10879949213aSStephan Aßmus 
10889949213aSStephan Aßmus 	jas_image_t* image;
10899949213aSStephan Aßmus 	jas_stream_t* ins;
10909949213aSStephan Aßmus 	jas_matrix_t* pixels[4];
10919949213aSStephan Aßmus 
10929949213aSStephan Aßmus 	if (jas_init())
10939949213aSStephan Aßmus 		return B_ERROR;
10949949213aSStephan Aßmus 
10959949213aSStephan Aßmus 	if (!(ins = jas_stream_positionIOopen(in)))
10969949213aSStephan Aßmus 		return B_ERROR;
10979949213aSStephan Aßmus 
10989949213aSStephan Aßmus 	if (!(image = jas_image_decode(ins, -1, 0)))
10999949213aSStephan Aßmus 		return Error(ins, NULL, NULL, 0, NULL, B_ERROR);
11009949213aSStephan Aßmus 
11019949213aSStephan Aßmus 	// Default color info
11029949213aSStephan Aßmus 	color_space out_color_space;
11039949213aSStephan Aßmus 	int out_color_components;
11049949213aSStephan Aßmus 	int	in_color_components = jas_image_numcmpts(image);
11059949213aSStephan Aßmus 
11069949213aSStephan Aßmus 	// Function pointer to read function
11079949213aSStephan Aßmus 	// It MUST point to proper function
1108fdfe641dSJérôme Duval 	void (*converter)(jas_matrix_t** pixels, uchar* outscanline,
110913eaf8faSStephan Aßmus 		int width) = NULL;
11109949213aSStephan Aßmus 
1111fdfe641dSJérôme Duval 	switch (jas_clrspc_fam(jas_image_clrspc(image))) {
1112fdfe641dSJérôme Duval 		case JAS_CLRSPC_FAM_RGB:
11139949213aSStephan Aßmus 			out_color_components = 4;
11149949213aSStephan Aßmus 			if (in_color_components == 3) {
11159949213aSStephan Aßmus 				out_color_space = B_RGB32;
11169949213aSStephan Aßmus 				converter = read_rgb24_to_rgb32;
11179949213aSStephan Aßmus 			} else if (in_color_components == 4) {
11189949213aSStephan Aßmus 				out_color_space = B_RGBA32;
11199949213aSStephan Aßmus 				converter = read_rgba32;
11209949213aSStephan Aßmus 			} else {
112170d59669SSiarzhuk Zharski 				syslog(LOG_ERR, "Other than RGB with 3 or 4 color "
112270d59669SSiarzhuk Zharski 					"components not implemented.\n");
11239949213aSStephan Aßmus 				return Error(ins, image, NULL, 0, NULL, B_ERROR);
11249949213aSStephan Aßmus 			}
11259949213aSStephan Aßmus 			break;
1126fdfe641dSJérôme Duval 		case JAS_CLRSPC_FAM_GRAY:
112794a204f0SStephan Aßmus 			if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) {
11289949213aSStephan Aßmus 				out_color_space = B_RGB32;
11299949213aSStephan Aßmus 				out_color_components = 4;
11309949213aSStephan Aßmus 				converter = read_gray_to_rgb32;
11319949213aSStephan Aßmus 			} else {
11329949213aSStephan Aßmus 				out_color_space = B_GRAY8;
11339949213aSStephan Aßmus 				out_color_components = 1;
11349949213aSStephan Aßmus 				converter = read_gray;
11359949213aSStephan Aßmus 			}
11369949213aSStephan Aßmus 			break;
1137fdfe641dSJérôme Duval 		case JAS_CLRSPC_FAM_YCBCR:
113870d59669SSiarzhuk Zharski 			syslog(LOG_ERR, "Color space YCBCR not implemented yet.\n");
11399949213aSStephan Aßmus 			return Error(ins, image, NULL, 0, NULL, B_ERROR);
11409949213aSStephan Aßmus 			break;
1141fdfe641dSJérôme Duval 		case JAS_CLRSPC_UNKNOWN:
11429949213aSStephan Aßmus 		default:
114370d59669SSiarzhuk Zharski 			syslog(LOG_ERR, "Color space unknown. \n");
11449949213aSStephan Aßmus 			return Error(ins, image, NULL, 0, NULL, B_ERROR);
11459949213aSStephan Aßmus 			break;
11469949213aSStephan Aßmus 	}
11479949213aSStephan Aßmus 
11489949213aSStephan Aßmus 	float width = (float)jas_image_width(image);
11499949213aSStephan Aßmus 	float height = (float)jas_image_height(image);
11509949213aSStephan Aßmus 
11519949213aSStephan Aßmus 	// Bytes count in one line of image (scanline)
11529949213aSStephan Aßmus 	int64 out_row_bytes = (int32)width * out_color_components;
11539949213aSStephan Aßmus 		// NOTE: things will go wrong if "out_row_bytes" wouldn't fit into 32 bits
11549949213aSStephan Aßmus 
11559949213aSStephan Aßmus 	// !!! Initialize this bounds rect to the size of your image
11569949213aSStephan Aßmus 	BRect bounds(0, 0, width - 1, height - 1);
11579949213aSStephan Aßmus 
115894a204f0SStephan Aßmus 
11599949213aSStephan Aßmus 	// Fill out the B_TRANSLATOR_BITMAP's header
11609949213aSStephan Aßmus 	TranslatorBitmap header;
11619949213aSStephan Aßmus 	header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP);
11629949213aSStephan Aßmus 	header.bounds.left = B_HOST_TO_BENDIAN_FLOAT(bounds.left);
11639949213aSStephan Aßmus 	header.bounds.top = B_HOST_TO_BENDIAN_FLOAT(bounds.top);
11649949213aSStephan Aßmus 	header.bounds.right = B_HOST_TO_BENDIAN_FLOAT(bounds.right);
11659949213aSStephan Aßmus 	header.bounds.bottom = B_HOST_TO_BENDIAN_FLOAT(bounds.bottom);
11669949213aSStephan Aßmus 	header.colors = (color_space)B_HOST_TO_BENDIAN_INT32(out_color_space);
11679949213aSStephan Aßmus 	header.rowBytes = B_HOST_TO_BENDIAN_INT32(out_row_bytes);
11689949213aSStephan Aßmus 	header.dataSize = B_HOST_TO_BENDIAN_INT32((int32)(out_row_bytes * height));
11699949213aSStephan Aßmus 
11709949213aSStephan Aßmus 	// Write out the header
11719949213aSStephan Aßmus 	status_t err = out->Write(&header, sizeof(TranslatorBitmap));
1172117da2d7SAxel Dörfler 	if (err < B_OK)
1173117da2d7SAxel Dörfler 		return Error(ins, image, NULL, 0, NULL, err);
1174117da2d7SAxel Dörfler 	if (err < (int)sizeof(TranslatorBitmap))
1175117da2d7SAxel Dörfler 		return Error(ins, image, NULL, 0, NULL, B_ERROR);
11769949213aSStephan Aßmus 
1177fdfe641dSJérôme Duval 	uchar *out_scanline = (uchar*) malloc(out_row_bytes);
1178117da2d7SAxel Dörfler 	if (out_scanline == NULL)
1179117da2d7SAxel Dörfler 		return Error(ins, image, NULL, 0, NULL, B_ERROR);
11809949213aSStephan Aßmus 
11819949213aSStephan Aßmus 	int32 i = 0;
1182117da2d7SAxel Dörfler 	for (i = 0; i < (long)in_color_components; i++) {
11839949213aSStephan Aßmus 		pixels[i] = jas_matrix_create(1, (unsigned int)width);
11849949213aSStephan Aßmus 		if (pixels[i] == (jas_matrix_t *)NULL)
11859949213aSStephan Aßmus 			return Error(ins, image, pixels, i + 1, out_scanline, B_ERROR);
11869949213aSStephan Aßmus 	}
11879949213aSStephan Aßmus 
11889949213aSStephan Aßmus 	int32 y = 0;
1189117da2d7SAxel Dörfler 	for (y = 0; y < (long)height; y++) {
119013eaf8faSStephan Aßmus 		for (i = 0; i < (long)in_color_components; i++) {
119113eaf8faSStephan Aßmus 			(void)jas_image_readcmpt(image, (short)i, 0, (unsigned int)y,
119213eaf8faSStephan Aßmus 				(unsigned int)width, 1, pixels[i]);
119313eaf8faSStephan Aßmus 		}
11949949213aSStephan Aßmus 
11959949213aSStephan Aßmus 		converter(pixels, out_scanline, (int32)width);
11969949213aSStephan Aßmus 
11979949213aSStephan Aßmus 		err = out->Write(out_scanline, out_row_bytes);
119813eaf8faSStephan Aßmus 		if (err < out_row_bytes) {
119994a204f0SStephan Aßmus 			return (err < B_OK) ? Error(ins, image, pixels, in_color_components,
120094a204f0SStephan Aßmus 				out_scanline, err)
120113eaf8faSStephan Aßmus 				: Error(ins, image, pixels, in_color_components, out_scanline,
120213eaf8faSStephan Aßmus 					B_ERROR);
120313eaf8faSStephan Aßmus 		}
12049949213aSStephan Aßmus 	}
12059949213aSStephan Aßmus 
12069949213aSStephan Aßmus 	free(out_scanline);
12079949213aSStephan Aßmus 
12089949213aSStephan Aßmus 	for (i = 0; i < (long)in_color_components; i++)
12099949213aSStephan Aßmus 		jas_matrix_destroy(pixels[i]);
1210117da2d7SAxel Dörfler 
12119949213aSStephan Aßmus 	jas_stream_close(ins);
12129949213aSStephan Aßmus 	jas_image_destroy(image);
12139949213aSStephan Aßmus 	jas_image_clearfmts();
12149949213aSStephan Aßmus 
12159949213aSStephan Aßmus 	return B_OK;
12169949213aSStephan Aßmus }
12179949213aSStephan Aßmus 
1218117da2d7SAxel Dörfler 
121994a204f0SStephan Aßmus /*! searches in both inputFormats & outputFormats */
122094a204f0SStephan Aßmus status_t
PopulateInfoFromFormat(translator_info * info,uint32 formatType,translator_id id)122194a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info,
122294a204f0SStephan Aßmus 	uint32 formatType, translator_id id)
122394a204f0SStephan Aßmus {
122494a204f0SStephan Aßmus 	int32 formatCount;
122594a204f0SStephan Aßmus 	const translation_format* formats = OutputFormats(&formatCount);
122694a204f0SStephan Aßmus 
122794a204f0SStephan Aßmus 	for (int i = 0; i <= 1; formats = InputFormats(&formatCount), i++) {
122894a204f0SStephan Aßmus 		if (PopulateInfoFromFormat(info, formatType,
122994a204f0SStephan Aßmus 			formats, formatCount) == B_OK) {
123094a204f0SStephan Aßmus 			info->translator = id;
123194a204f0SStephan Aßmus 			return B_OK;
123294a204f0SStephan Aßmus 		}
123394a204f0SStephan Aßmus 	}
123494a204f0SStephan Aßmus 
123594a204f0SStephan Aßmus 	return B_ERROR;
123694a204f0SStephan Aßmus }
123794a204f0SStephan Aßmus 
123894a204f0SStephan Aßmus 
123994a204f0SStephan Aßmus status_t
PopulateInfoFromFormat(translator_info * info,uint32 formatType,const translation_format * formats,int32 formatCount)124094a204f0SStephan Aßmus JP2Translator::PopulateInfoFromFormat(translator_info* info,
124194a204f0SStephan Aßmus 	uint32 formatType, const translation_format* formats, int32 formatCount)
124294a204f0SStephan Aßmus {
124394a204f0SStephan Aßmus 	for (int i = 0; i < formatCount; i++) {
124494a204f0SStephan Aßmus 		if (formats[i].type == formatType) {
124594a204f0SStephan Aßmus 			info->type = formatType;
124694a204f0SStephan Aßmus 			info->group = formats[i].group;
124794a204f0SStephan Aßmus 			info->quality = formats[i].quality;
124894a204f0SStephan Aßmus 			info->capability = formats[i].capability;
1249e5928728SFranck LeCodeur 			if (strcmp(formats[i].name, B_TRANSLATOR_BITMAP_DESCRIPTION)
1250e5928728SFranck LeCodeur 				== 0) {
1251e5928728SFranck LeCodeur 				strlcpy(info->name,
1252e5928728SFranck LeCodeur 					B_TRANSLATE(B_TRANSLATOR_BITMAP_DESCRIPTION),
1253c44966dfSJérôme Duval 					sizeof(info->name));
1254e5928728SFranck LeCodeur 			} else {
1255e5928728SFranck LeCodeur 				strlcpy(info->name, formats[i].name, sizeof(info->name));
1256e5928728SFranck LeCodeur 			}
1257e5928728SFranck LeCodeur 			strlcpy(info->MIME, formats[i].MIME, sizeof(info->MIME));
125894a204f0SStephan Aßmus 			return B_OK;
125994a204f0SStephan Aßmus 		}
126094a204f0SStephan Aßmus 	}
126194a204f0SStephan Aßmus 
126294a204f0SStephan Aßmus 	return B_ERROR;
126394a204f0SStephan Aßmus }
126494a204f0SStephan Aßmus 
126594a204f0SStephan Aßmus 
1266117da2d7SAxel Dörfler /*!
1267117da2d7SAxel Dörfler 	Frees jpeg alocated memory
1268117da2d7SAxel Dörfler 	Returns given error (B_ERROR by default)
1269117da2d7SAxel Dörfler */
12709949213aSStephan Aßmus status_t
Error(jas_stream_t * stream,jas_image_t * image,jas_matrix_t ** pixels,int32 pixels_count,uchar * scanline,status_t error)127113eaf8faSStephan Aßmus Error(jas_stream_t* stream, jas_image_t* image, jas_matrix_t** pixels,
1272fdfe641dSJérôme Duval 	int32 pixels_count, uchar* scanline, status_t error)
12739949213aSStephan Aßmus {
1274117da2d7SAxel Dörfler 	if (pixels) {
12759949213aSStephan Aßmus 		int32 i;
1276117da2d7SAxel Dörfler 		for (i = 0; i < (long)pixels_count; i++) {
12779949213aSStephan Aßmus 			if (pixels[i] != NULL)
12789949213aSStephan Aßmus 				jas_matrix_destroy(pixels[i]);
12799949213aSStephan Aßmus 		}
1280117da2d7SAxel Dörfler 	}
12819949213aSStephan Aßmus 	if (stream)
12829949213aSStephan Aßmus 		jas_stream_close(stream);
12839949213aSStephan Aßmus 	if (image)
12849949213aSStephan Aßmus 		jas_image_destroy(image);
1285117da2d7SAxel Dörfler 
12869949213aSStephan Aßmus 	jas_image_clearfmts();
12879949213aSStephan Aßmus 	free(scanline);
12889949213aSStephan Aßmus 
12899949213aSStephan Aßmus 	return error;
12909949213aSStephan Aßmus }
1291117da2d7SAxel Dörfler 
1292117da2d7SAxel Dörfler 
1293117da2d7SAxel Dörfler //	#pragma mark -
1294117da2d7SAxel Dörfler 
129594a204f0SStephan Aßmus BTranslator*
make_nth_translator(int32 n,image_id you,uint32 flags,...)129694a204f0SStephan Aßmus make_nth_translator(int32 n, image_id you, uint32 flags, ...)
129794a204f0SStephan Aßmus {
129894a204f0SStephan Aßmus 	if (!n)
129994a204f0SStephan Aßmus 		return new JP2Translator();
130094a204f0SStephan Aßmus 
130194a204f0SStephan Aßmus 	return NULL;
130294a204f0SStephan Aßmus }
130394a204f0SStephan Aßmus 
1304117da2d7SAxel Dörfler 
1305117da2d7SAxel Dörfler int
main()1306117da2d7SAxel Dörfler main()
1307117da2d7SAxel Dörfler {
1308117da2d7SAxel Dörfler 	BApplication app("application/x-vnd.Haiku-JPEG2000Translator");
130994a204f0SStephan Aßmus 	JP2Translator* translator = new JP2Translator();
131070d59669SSiarzhuk Zharski 	if (LaunchTranslatorWindow(translator, sTranslatorName) == B_OK)
1311117da2d7SAxel Dörfler 		app.Run();
131294a204f0SStephan Aßmus 
1313117da2d7SAxel Dörfler 	return 0;
1314117da2d7SAxel Dörfler }
1315117da2d7SAxel Dörfler 
1316