1 /*
2
3 Copyright (c) 2003, Marcin 'Shard' Konicki
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9 * Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation and/or
13 other materials provided with the distribution.
14 * Name "Marcin Konicki", "Shard" or any combination of them,
15 must not be used to endorse or promote products derived from this
16 software without specific prior written permission from Marcin Konicki.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 */
31
32
33 #include "JPEG2000Translator.h"
34 #include "TranslatorWindow.h"
35
36 #include <syslog.h>
37
38 #include <LayoutBuilder.h>
39 #include <TabView.h>
40 #include <TextView.h>
41
42
43 #undef B_TRANSLATION_CONTEXT
44 #define B_TRANSLATION_CONTEXT "JPEG2000Translator"
45
46 // Set these accordingly
47 #define JP2_ACRONYM "JP2"
48 #define JP2_FORMAT 'JP2 '
49 #define JP2_MIME_STRING "image/jp2"
50 #define JP2_DESCRIPTION "JPEG2000 image"
51
52 // The translation kit's native file type
53 #define B_TRANSLATOR_BITMAP_MIME_STRING "image/x-be-bitmap"
54 #define B_TRANSLATOR_BITMAP_DESCRIPTION "Be Bitmap Format (JPEG2000Translator)"
55
56 static int32 sTranslatorVersion = B_TRANSLATION_MAKE_VERSION(1, 0, 0);
57
58 static const char* sTranslatorName = B_TRANSLATE("JPEG2000 images");
59 static const char* sTranslatorInfo = B_TRANSLATE("©2002-2003, Shard\n"
60 "©2005-2006, Haiku\n"
61 "\n"
62 "Based on JasPer library:\n"
63 "© 1999-2000, Image Power, Inc. and\n"
64 "the University of British Columbia, Canada.\n"
65 "© 2001-2003 Michael David Adams.\n"
66 "\thttp://www.ece.uvic.ca/~mdadams/jasper/\n"
67 "\n"
68 "ImageMagick's jp2 codec was used as \"tutorial\".\n"
69 "\thttp://www.imagemagick.org/\n");
70
71 static const translation_format sInputFormats[] = {
72 { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5,
73 JP2_MIME_STRING, JP2_DESCRIPTION },
74 { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5,
75 B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION },
76 };
77
78 static const translation_format sOutputFormats[] = {
79 { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5,
80 JP2_MIME_STRING, JP2_DESCRIPTION },
81 { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5,
82 B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION },
83 };
84
85
86 static const TranSetting sDefaultSettings[] = {
87 {JP2_SET_QUALITY, TRAN_SETTING_INT32, 25},
88 {JP2_SET_JPC, TRAN_SETTING_BOOL, false},
89 {JP2_SET_GRAY1_AS_B_RGB24, TRAN_SETTING_BOOL, false},
90 {JP2_SET_GRAY8_AS_B_RGB32, TRAN_SETTING_BOOL, true}
91 };
92
93 const uint32 kNumInputFormats = sizeof(sInputFormats) / sizeof(translation_format);
94 const uint32 kNumOutputFormats = sizeof(sOutputFormats) / sizeof(translation_format);
95 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings) / sizeof(TranSetting);
96
97
98 #define JP2_BOX_JP 0x6a502020
99 #define JPC_MS_SOC 0xff4f
100
101
102 namespace conversion{
103 //! Make RGB32 scanline from *pixels[3]
104 inline void
read_rgb24_to_rgb32(jas_matrix_t ** pixels,uchar * scanline,int width)105 read_rgb24_to_rgb32(jas_matrix_t** pixels, uchar* scanline, int width)
106 {
107 int32 index = 0;
108 int32 x = 0;
109 while (x < width) {
110 scanline[index++] = (uchar)jas_matrix_getv(pixels[2], x);
111 scanline[index++] = (uchar)jas_matrix_getv(pixels[1], x);
112 scanline[index++] = (uchar)jas_matrix_getv(pixels[0], x);
113 scanline[index++] = 255;
114 x++;
115 }
116 }
117
118
119 //! Make gray scanline from *pixels[1]
120 inline void
read_gray_to_rgb32(jas_matrix_t ** pixels,uchar * scanline,int width)121 read_gray_to_rgb32(jas_matrix_t** pixels, uchar* scanline, int width)
122 {
123 int32 index = 0;
124 int32 x = 0;
125 uchar color = 0;
126 while (x < width) {
127 color = (uchar)jas_matrix_getv(pixels[0], x++);
128 scanline[index++] = color;
129 scanline[index++] = color;
130 scanline[index++] = color;
131 scanline[index++] = 255;
132 }
133 }
134
135
136 /*!
137 Make RGBA32 scanline from *pixels[4]
138 (just read data to scanline)
139 */
140 inline void
read_rgba32(jas_matrix_t ** pixels,uchar * scanline,int width)141 read_rgba32(jas_matrix_t** pixels, uchar *scanline, int width)
142 {
143 int32 index = 0;
144 int32 x = 0;
145 while (x < width) {
146 scanline[index++] = (uchar)jas_matrix_getv(pixels[2], x);
147 scanline[index++] = (uchar)jas_matrix_getv(pixels[1], x);
148 scanline[index++] = (uchar)jas_matrix_getv(pixels[0], x);
149 scanline[index++] = (uchar)jas_matrix_getv(pixels[3], x);
150 x++;
151 }
152 }
153
154
155 /*!
156 Make gray scanline from *pixels[1]
157 (just read data to scanline)
158 */
159 inline void
read_gray(jas_matrix_t ** pixels,uchar * scanline,int width)160 read_gray(jas_matrix_t** pixels, uchar* scanline, int width)
161 {
162 int32 x = 0;
163 while (x < width) {
164 scanline[x] = (uchar)jas_matrix_getv(pixels[0], x);
165 x++;
166 }
167 }
168
169
170 //! Make *pixels[1] from gray1 scanline
171 inline void
write_gray1_to_gray(jas_matrix_t ** pixels,uchar * scanline,int width)172 write_gray1_to_gray(jas_matrix_t** pixels, uchar* scanline, int width)
173 {
174 int32 x = 0;
175 int32 index = 0;
176 while (x < (width/8)) {
177 unsigned char c = scanline[x++];
178 for (int b = 128; b; b = b >> 1) {
179 if (c & b)
180 jas_matrix_setv(pixels[0], index++, 0);
181 else
182 jas_matrix_setv(pixels[0], index++, 255);
183 }
184 }
185 }
186
187
188 //! Make *pixels[3] from gray1 scanline
189 inline void
write_gray1_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)190 write_gray1_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
191 {
192 int32 x = 0;
193 int32 index = 0;
194 while (x < (width / 8)) {
195 unsigned char c = scanline[x++];
196 for (int b = 128; b; b = b >> 1) {
197 if (c & b) {
198 jas_matrix_setv(pixels[0], index, 0);
199 jas_matrix_setv(pixels[1], index, 0);
200 jas_matrix_setv(pixels[2], index, 0);
201 } else {
202 jas_matrix_setv(pixels[0], index, 255);
203 jas_matrix_setv(pixels[1], index, 255);
204 jas_matrix_setv(pixels[2], index, 255);
205 }
206 index++;
207 }
208 }
209 }
210
211
212 //! Make *pixels[3] from cmap8 scanline
213 inline void
write_cmap8_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)214 write_cmap8_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
215 {
216 const color_map* map = system_colors();
217 int32 x = 0;
218 while (x < width) {
219 rgb_color color = map->color_list[scanline[x]];
220
221 jas_matrix_setv(pixels[0], x, color.red);
222 jas_matrix_setv(pixels[1], x, color.green);
223 jas_matrix_setv(pixels[2], x, color.blue);
224 x++;
225 }
226 }
227
228
229 /*!
230 Make *pixels[1] from gray scanline
231 (just write data to pixels)
232 */
233 inline void
write_gray(jas_matrix_t ** pixels,uchar * scanline,int width)234 write_gray(jas_matrix_t** pixels, uchar* scanline, int width)
235 {
236 int32 x = 0;
237 while (x < width) {
238 jas_matrix_setv(pixels[0], x, scanline[x]);
239 x++;
240 }
241 }
242
243
244 /*!
245 Make *pixels[3] from RGB15/RGBA15 scanline
246 (just write data to pixels)
247 */
248 inline void
write_rgb15_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)249 write_rgb15_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
250 {
251 int32 x = 0;
252 int32 index = 0;
253 int16 in_pixel;
254 while (x < width) {
255 in_pixel = scanline[index] | (scanline[index+1] << 8);
256 index += 2;
257
258 jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7)
259 | (((in_pixel & 0x7c00)) >> 12));
260 jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2)
261 | (((in_pixel & 0x3e0)) >> 7));
262 jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
263 | (((in_pixel & 0x1f)) >> 2));
264 x++;
265 }
266 }
267
268
269 /*!
270 Make *pixels[3] from RGB15/RGBA15 bigendian scanline
271 (just write data to pixels)
272 */
273 inline void
write_rgb15b_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)274 write_rgb15b_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
275 {
276 int32 x = 0;
277 int32 index = 0;
278 int16 in_pixel;
279 while (x < width) {
280 in_pixel = scanline[index + 1] | (scanline[index] << 8);
281 index += 2;
282
283 jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7)
284 | (((in_pixel & 0x7c00)) >> 12));
285 jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2)
286 | (((in_pixel & 0x3e0)) >> 7));
287 jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
288 | (((in_pixel & 0x1f)) >> 2));
289 x++;
290 }
291 }
292
293
294 /*!
295 Make *pixels[3] from RGB16/RGBA16 scanline
296 (just write data to pixels)
297 */
298 inline void
write_rgb16_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)299 write_rgb16_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
300 {
301 int32 x = 0;
302 int32 index = 0;
303 int16 in_pixel;
304 while (x < width) {
305 in_pixel = scanline[index] | (scanline[index+1] << 8);
306 index += 2;
307
308 jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8)
309 | (((in_pixel & 0x7c00)) >> 12));
310 jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3)
311 | (((in_pixel & 0x7e0)) >> 9));
312 jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
313 | (((in_pixel & 0x1f)) >> 2));
314 x++;
315 }
316 }
317
318
319 /*!
320 Make *pixels[3] from RGB16/RGBA16 bigendian scanline
321 (just write data to pixels)
322 */
323 inline void
write_rgb16b_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)324 write_rgb16b_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
325 {
326 int32 x = 0;
327 int32 index = 0;
328 int16 in_pixel;
329 while (x < width) {
330 in_pixel = scanline[index + 1] | (scanline[index] << 8);
331 index += 2;
332
333 jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8)
334 | (((in_pixel & 0xf800)) >> 13));
335 jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3)
336 | (((in_pixel & 0x7e0)) >> 9));
337 jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
338 | (((in_pixel & 0x1f)) >> 2));
339 x++;
340 }
341 }
342
343
344 /*!
345 Make *pixels[3] from RGB24 scanline
346 (just write data to pixels)
347 */
348 inline void
write_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)349 write_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
350 {
351 int32 index = 0;
352 int32 x = 0;
353 while (x < width) {
354 jas_matrix_setv(pixels[2], x, scanline[index++]);
355 jas_matrix_setv(pixels[1], x, scanline[index++]);
356 jas_matrix_setv(pixels[0], x, scanline[index++]);
357 x++;
358 }
359 }
360
361
362 /*!
363 Make *pixels[3] from RGB24 bigendian scanline
364 (just write data to pixels)
365 */
366 inline void
write_rgb24b(jas_matrix_t ** pixels,uchar * scanline,int width)367 write_rgb24b(jas_matrix_t** pixels, uchar* scanline, int width)
368 {
369 int32 index = 0;
370 int32 x = 0;
371 while (x < width) {
372 jas_matrix_setv(pixels[0], x, scanline[index++]);
373 jas_matrix_setv(pixels[1], x, scanline[index++]);
374 jas_matrix_setv(pixels[2], x, scanline[index++]);
375 x++;
376 }
377 }
378
379
380 /*!
381 Make *pixels[3] from RGB32 scanline
382 (just write data to pixels)
383 */
384 inline void
write_rgb32_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)385 write_rgb32_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
386 {
387 int32 index = 0;
388 int32 x = 0;
389 while (x < width) {
390 jas_matrix_setv(pixels[2], x, scanline[index++]);
391 jas_matrix_setv(pixels[1], x, scanline[index++]);
392 jas_matrix_setv(pixels[0], x, scanline[index++]);
393 index++;
394 x++;
395 }
396 }
397
398
399 /*!
400 Make *pixels[3] from RGB32 bigendian scanline
401 (just write data to pixels)
402 */
403 inline void
write_rgb32b_to_rgb24(jas_matrix_t ** pixels,uchar * scanline,int width)404 write_rgb32b_to_rgb24(jas_matrix_t** pixels, uchar* scanline, int width)
405 {
406 int32 index = 0;
407 int32 x = 0;
408 while (x < width) {
409 index++;
410 jas_matrix_setv(pixels[0], x, scanline[index++]);
411 jas_matrix_setv(pixels[1], x, scanline[index++]);
412 jas_matrix_setv(pixels[2], x, scanline[index++]);
413 x++;
414 }
415 }
416
417
418 /*!
419 Make *pixels[4] from RGBA32 scanline
420 (just write data to pixels)
421 !!! UNTESTED !!!
422 */
423 inline void
write_rgba32(jas_matrix_t ** pixels,uchar * scanline,int width)424 write_rgba32(jas_matrix_t** pixels, uchar* scanline, int width)
425 {
426 int32 index = 0;
427 int32 x = 0;
428 while (x < width) {
429 jas_matrix_setv(pixels[3], x, scanline[index++]);
430 jas_matrix_setv(pixels[2], x, scanline[index++]);
431 jas_matrix_setv(pixels[1], x, scanline[index++]);
432 jas_matrix_setv(pixels[0], x, scanline[index++]);
433 x++;
434 }
435 }
436
437
438 /*!
439 Make *pixels[4] from RGBA32 bigendian scanline
440 (just write data to pixels)
441 !!! UNTESTED !!!
442 */
443 inline void
write_rgba32b(jas_matrix_t ** pixels,uchar * scanline,int width)444 write_rgba32b(jas_matrix_t** pixels, uchar* scanline, int width)
445 {
446 int32 index = 0;
447 int32 x = 0;
448 while (x < width) {
449 jas_matrix_setv(pixels[0], x, scanline[index++]);
450 jas_matrix_setv(pixels[1], x, scanline[index++]);
451 jas_matrix_setv(pixels[2], x, scanline[index++]);
452 jas_matrix_setv(pixels[3], x, scanline[index++]);
453 x++;
454 }
455 }
456
457
458 }// end namespace conversion
459
460
461 // #pragma mark - jasper I/O
462
463
464 #if __GNUC__ == 2
465 typedef int jasper_length_t;
466 #else
467 typedef unsigned int jasper_length_t;
468 #endif
469
470
471 static int
Read(jas_stream_obj_t * object,char * buffer,const jasper_length_t length)472 Read(jas_stream_obj_t* object, char* buffer, const jasper_length_t length)
473 {
474 return (*(BPositionIO**)object)->Read(buffer, length);
475 }
476
477
478 static int
Write(jas_stream_obj_t * object,const char * buffer,const jasper_length_t length)479 Write(jas_stream_obj_t* object, const char* buffer, const jasper_length_t length)
480 {
481 return (*(BPositionIO**)object)->Write(buffer, length);
482 }
483
484
485 static long
Seek(jas_stream_obj_t * object,long offset,int origin)486 Seek(jas_stream_obj_t* object, long offset, int origin)
487 {
488 return (*(BPositionIO**)object)->Seek(offset, origin);
489 }
490
491
492 static int
Close(jas_stream_obj_t * object)493 Close(jas_stream_obj_t* object)
494 {
495 return 0;
496 }
497
498
499 static jas_stream_ops_t positionIOops = {
500 Read,
501 Write,
502 Seek,
503 Close
504 };
505
506
507 static jas_stream_t*
jas_stream_positionIOopen(BPositionIO * positionIO)508 jas_stream_positionIOopen(BPositionIO *positionIO)
509 {
510 jas_stream_t* stream;
511
512 stream = (jas_stream_t *)malloc(sizeof(jas_stream_t));
513 if (stream == (jas_stream_t *)NULL)
514 return (jas_stream_t *)NULL;
515
516 memset(stream, 0, sizeof(jas_stream_t));
517 stream->rwlimit_ = -1;
518 stream->obj_=(jas_stream_obj_t *)malloc(sizeof(BPositionIO*));
519 if (stream->obj_ == (jas_stream_obj_t *)NULL) {
520 free(stream);
521 return (jas_stream_t *)NULL;
522 }
523
524 *((BPositionIO**)stream->obj_) = positionIO;
525 stream->ops_ = (&positionIOops);
526 stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY;
527 stream->bufbase_ = stream->tinybuf_;
528 stream->bufsize_ = 1;
529 stream->bufstart_ = (&stream->bufbase_[JAS_STREAM_MAXPUTBACK]);
530 stream->ptr_ = stream->bufstart_;
531 stream->bufmode_ |= JAS_STREAM_UNBUF & JAS_STREAM_BUFMODEMASK;
532
533 return stream;
534 }
535
536
537 // #pragma mark -
538
539
SSlider(const char * name,const char * label,BMessage * message,int32 minValue,int32 maxValue,orientation posture,thumb_style thumbType,uint32 flags)540 SSlider::SSlider(const char* name, const char* label,
541 BMessage* message, int32 minValue, int32 maxValue, orientation posture,
542 thumb_style thumbType, uint32 flags)
543 :
544 BSlider(name, label, message, minValue, maxValue,
545 posture, thumbType, flags)
546 {
547 rgb_color barColor = { 0, 0, 229, 255 };
548 UseFillColor(true, &barColor);
549 }
550
551
552 //! Update status string - show actual value
553 const char*
UpdateText() const554 SSlider::UpdateText() const
555 {
556 snprintf(fStatusLabel, sizeof(fStatusLabel), "%" B_PRId32, Value());
557 return fStatusLabel;
558 }
559
560
561 // #pragma mark -
562
563
TranslatorReadView(const char * name,TranslatorSettings * settings)564 TranslatorReadView::TranslatorReadView(const char* name,
565 TranslatorSettings* settings)
566 :
567 BView(name, 0, new BGroupLayout(B_VERTICAL)),
568 fSettings(settings)
569 {
570 fGrayAsRGB32 = new BCheckBox("grayasrgb32",
571 B_TRANSLATE("Read greyscale images as RGB32"),
572 new BMessage(VIEW_MSG_SET_GRAYASRGB32));
573 if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32))
574 fGrayAsRGB32->SetValue(B_CONTROL_ON);
575
576 float padding = 10.0f;
577 BLayoutBuilder::Group<>(this, B_VERTICAL)
578 .SetInsets(padding)
579 .Add(fGrayAsRGB32)
580 .AddGlue();
581 }
582
583
~TranslatorReadView()584 TranslatorReadView::~TranslatorReadView()
585 {
586 fSettings->Release();
587 }
588
589
590 void
AttachedToWindow()591 TranslatorReadView::AttachedToWindow()
592 {
593 fGrayAsRGB32->SetTarget(this);
594 }
595
596
597 void
MessageReceived(BMessage * message)598 TranslatorReadView::MessageReceived(BMessage* message)
599 {
600 switch (message->what) {
601 case VIEW_MSG_SET_GRAYASRGB32:
602 {
603 int32 value;
604 if (message->FindInt32("be:value", &value) == B_OK) {
605 bool boolValue = value;
606 fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32, &boolValue);
607 fSettings->SaveSettings();
608 }
609 break;
610 }
611 default:
612 BView::MessageReceived(message);
613 break;
614 }
615 }
616
617
618 // #pragma mark - TranslatorWriteView
619
620
TranslatorWriteView(const char * name,TranslatorSettings * settings)621 TranslatorWriteView::TranslatorWriteView(const char* name,
622 TranslatorSettings* settings)
623 :
624 BView(name, 0, new BGroupLayout(B_VERTICAL)),
625 fSettings(settings)
626 {
627 fQualitySlider = new SSlider("quality", B_TRANSLATE("Output quality"),
628 new BMessage(VIEW_MSG_SET_QUALITY), 0, 100);
629 fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
630 fQualitySlider->SetHashMarkCount(10);
631 fQualitySlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High"));
632 fQualitySlider->SetValue(fSettings->SetGetInt32(JP2_SET_QUALITY));
633
634 fGrayAsRGB24 = new BCheckBox("gray1asrgb24",
635 B_TRANSLATE("Write black-and-white images as RGB24"),
636 new BMessage(VIEW_MSG_SET_GRAY1ASRGB24));
637 if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24))
638 fGrayAsRGB24->SetValue(B_CONTROL_ON);
639
640 fCodeStreamOnly = new BCheckBox("codestreamonly",
641 B_TRANSLATE("Output only codestream (.jpc)"),
642 new BMessage(VIEW_MSG_SET_JPC));
643 if (fSettings->SetGetBool(JP2_SET_JPC))
644 fCodeStreamOnly->SetValue(B_CONTROL_ON);
645
646 BLayoutBuilder::Group<>(this, B_VERTICAL)
647 .SetInsets(B_USE_DEFAULT_SPACING)
648 .Add(fQualitySlider)
649 .Add(fGrayAsRGB24)
650 .Add(fCodeStreamOnly)
651 .AddGlue();
652 }
653
654
~TranslatorWriteView()655 TranslatorWriteView::~TranslatorWriteView()
656 {
657 fSettings->Release();
658 }
659
660
661 void
AttachedToWindow()662 TranslatorWriteView::AttachedToWindow()
663 {
664 fQualitySlider->SetTarget(this);
665 fGrayAsRGB24->SetTarget(this);
666 fCodeStreamOnly->SetTarget(this);
667 }
668
669
670 void
MessageReceived(BMessage * message)671 TranslatorWriteView::MessageReceived(BMessage* message)
672 {
673 switch (message->what) {
674 case VIEW_MSG_SET_QUALITY:
675 {
676 int32 value;
677 if (message->FindInt32("be:value", &value) == B_OK) {
678 fSettings->SetGetInt32(JP2_SET_QUALITY, &value);
679 fSettings->SaveSettings();
680 }
681 break;
682 }
683 case VIEW_MSG_SET_GRAY1ASRGB24:
684 {
685 int32 value;
686 if (message->FindInt32("be:value", &value) == B_OK) {
687 bool boolValue = value;
688 fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24, &boolValue);
689 fSettings->SaveSettings();
690 }
691 break;
692 }
693 case VIEW_MSG_SET_JPC:
694 {
695 int32 value;
696 if (message->FindInt32("be:value", &value) == B_OK) {
697 bool boolValue = value;
698 fSettings->SetGetBool(JP2_SET_JPC, &boolValue);
699 fSettings->SaveSettings();
700 }
701 break;
702 }
703 default:
704 BView::MessageReceived(message);
705 break;
706 }
707 }
708
709
710 // #pragma mark -
711
712
TranslatorAboutView(const char * name)713 TranslatorAboutView::TranslatorAboutView(const char* name)
714 :
715 BView(name, 0, new BGroupLayout(B_VERTICAL))
716 {
717 BAlignment labelAlignment = BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
718 BStringView* title = new BStringView("Title", sTranslatorName);
719 title->SetFont(be_bold_font);
720 title->SetExplicitAlignment(labelAlignment);
721
722 char versionString[100];
723 snprintf(versionString, sizeof(versionString),
724 B_TRANSLATE("Version %d.%d.%d"),
725 static_cast<int>(sTranslatorVersion >> 8),
726 static_cast<int>((sTranslatorVersion >> 4) & 0xf),
727 static_cast<int>(sTranslatorVersion & 0xf));
728
729 BStringView* version = new BStringView("Version", versionString);
730 version->SetExplicitAlignment(labelAlignment);
731
732 BTextView* infoView = new BTextView("info");
733 infoView->SetText(sTranslatorInfo);
734 infoView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
735 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
736 infoView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
737 infoView->MakeEditable(false);
738
739 BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
740 .SetInsets(B_USE_DEFAULT_SPACING)
741 .Add(title)
742 .Add(version)
743 .Add(infoView);
744 }
745
746
747 // #pragma mark -
748
749
TranslatorView(const char * name,TranslatorSettings * settings)750 TranslatorView::TranslatorView(const char* name, TranslatorSettings* settings)
751 :
752 BTabView(name, B_WIDTH_FROM_LABEL)
753 {
754 SetBorder(B_NO_BORDER);
755
756 AddTab(new TranslatorWriteView(B_TRANSLATE("Write"),
757 settings->Acquire()));
758 AddTab(new TranslatorReadView(B_TRANSLATE("Read"),
759 settings->Acquire()));
760 AddTab(new TranslatorAboutView(B_TRANSLATE("About")));
761
762 settings->Release();
763 }
764
765
766 // #pragma mark -
767
768 BView*
NewConfigView(TranslatorSettings * settings)769 JP2Translator::NewConfigView(TranslatorSettings* settings)
770 {
771 BView* outView = new TranslatorView("TranslatorView", settings);
772 return outView;
773 }
774
775
JP2Translator()776 JP2Translator::JP2Translator()
777 : BaseTranslator(sTranslatorName, sTranslatorInfo, sTranslatorVersion,
778 sInputFormats, kNumInputFormats,
779 sOutputFormats, kNumOutputFormats,
780 JP2_SETTINGS_FILE,
781 sDefaultSettings, kNumDefaultSettings,
782 B_TRANSLATOR_BITMAP, JP2_FORMAT)
783 {
784 }
785
786
787 //! Determine whether or not we can handle this data
788 status_t
DerivedIdentify(BPositionIO * inSource,const translation_format * inFormat,BMessage * ioExtension,translator_info * outInfo,uint32 outType)789 JP2Translator::DerivedIdentify(BPositionIO* inSource,
790 const translation_format* inFormat, BMessage* ioExtension,
791 translator_info* outInfo, uint32 outType)
792 {
793 if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP)
794 && outType != JP2_FORMAT)
795 return B_NO_TRANSLATOR;
796
797 // !!! You might need to make this buffer bigger to test for your
798 // native format
799 off_t position = inSource->Position();
800 uint8 header[sizeof(TranslatorBitmap)];
801 status_t err = inSource->Read(header, sizeof(TranslatorBitmap));
802 inSource->Seek(position, SEEK_SET);
803 if (err < B_OK)
804 return err;
805
806 if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic)
807 == B_TRANSLATOR_BITMAP) {
808 if (PopulateInfoFromFormat(outInfo, B_TRANSLATOR_BITMAP) != B_OK)
809 return B_NO_TRANSLATOR;
810 } else {
811 if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8)
812 | header[7]) == JP2_BOX_JP) // JP2
813 || (header[0] == (JPC_MS_SOC >> 8) && header[1]
814 == (JPC_MS_SOC & 0xff))) // JPC
815 {
816 if (PopulateInfoFromFormat(outInfo, JP2_FORMAT) != B_OK)
817 return B_NO_TRANSLATOR;
818 } else
819 return B_NO_TRANSLATOR;
820 }
821
822 return B_OK;
823 }
824
825
826 status_t
DerivedTranslate(BPositionIO * inSource,const translator_info * inInfo,BMessage * ioExtension,uint32 outType,BPositionIO * outDestination,int32 baseType)827 JP2Translator::DerivedTranslate(BPositionIO* inSource,
828 const translator_info* inInfo, BMessage* ioExtension, uint32 outType,
829 BPositionIO* outDestination, int32 baseType)
830 {
831 // If no specific type was requested, convert to the interchange format
832 if (outType == 0)
833 outType = B_TRANSLATOR_BITMAP;
834
835 // What action to take, based on the findings of Identify()
836 if (outType == inInfo->type)
837 return Copy(inSource, outDestination);
838 if (inInfo->type == B_TRANSLATOR_BITMAP && outType == JP2_FORMAT)
839 return Compress(inSource, outDestination);
840 if (inInfo->type == JP2_FORMAT && outType == B_TRANSLATOR_BITMAP)
841 return Decompress(inSource, outDestination);
842
843 return B_NO_TRANSLATOR;
844 }
845
846
847 //! The user has requested the same format for input and output, so just copy
848 status_t
Copy(BPositionIO * in,BPositionIO * out)849 JP2Translator::Copy(BPositionIO* in, BPositionIO* out)
850 {
851 int block_size = 65536;
852 void* buffer = malloc(block_size);
853 char temp[1024];
854 if (buffer == NULL) {
855 buffer = temp;
856 block_size = 1024;
857 }
858 status_t err = B_OK;
859
860 // Read until end of file or error
861 while (1) {
862 ssize_t to_read = block_size;
863 err = in->Read(buffer, to_read);
864 // Explicit check for EOF
865 if (err == -1) {
866 if (buffer != temp)
867 free(buffer);
868 return B_OK;
869 }
870 if (err <= B_OK) break;
871 to_read = err;
872 err = out->Write(buffer, to_read);
873 if (err != to_read) if (err >= 0) err = B_DEVICE_FULL;
874 if (err < B_OK) break;
875 }
876
877 if (buffer != temp)
878 free(buffer);
879 return (err >= 0) ? B_OK : err;
880 }
881
882
883 //! Encode into the native format
884 status_t
Compress(BPositionIO * in,BPositionIO * out)885 JP2Translator::Compress(BPositionIO* in, BPositionIO* out)
886 {
887 using namespace conversion;
888
889 // Read info about bitmap
890 TranslatorBitmap header;
891 status_t err = in->Read(&header, sizeof(TranslatorBitmap));
892 if (err < B_OK)
893 return err;
894 if (err < (int)sizeof(TranslatorBitmap))
895 return B_ERROR;
896
897 // Grab dimension, color space, and size information from the stream
898 BRect bounds;
899 bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left);
900 bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top);
901 bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right);
902 bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
903
904 int32 in_row_bytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
905
906 int width = bounds.IntegerWidth() + 1;
907 int height = bounds.IntegerHeight() + 1;
908
909 // Function pointer to write function
910 // It MUST point to proper function
911 void (*converter)(jas_matrix_t** pixels, uchar* inscanline,
912 int width) = write_rgba32;
913
914 // Default color info
915 int out_color_space = JAS_CLRSPC_SRGB;
916 int out_color_components = 3;
917
918 switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) {
919 case B_GRAY1:
920 if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) {
921 converter = write_gray1_to_rgb24;
922 } else {
923 out_color_components = 1;
924 out_color_space = JAS_CLRSPC_SGRAY;
925 converter = write_gray1_to_gray;
926 }
927 break;
928
929 case B_CMAP8:
930 converter = write_cmap8_to_rgb24;
931 break;
932
933 case B_GRAY8:
934 out_color_components = 1;
935 out_color_space = JAS_CLRSPC_SGRAY;
936 converter = write_gray;
937 break;
938
939 case B_RGB15:
940 case B_RGBA15:
941 converter = write_rgb15_to_rgb24;
942 break;
943
944 case B_RGB15_BIG:
945 case B_RGBA15_BIG:
946 converter = write_rgb15b_to_rgb24;
947 break;
948
949 case B_RGB16:
950 converter = write_rgb16_to_rgb24;
951 break;
952
953 case B_RGB16_BIG:
954 converter = write_rgb16b_to_rgb24;
955 break;
956
957 case B_RGB24:
958 converter = write_rgb24;
959 break;
960
961 case B_RGB24_BIG:
962 converter = write_rgb24b;
963 break;
964
965 case B_RGB32:
966 converter = write_rgb32_to_rgb24;
967 break;
968
969 case B_RGB32_BIG:
970 converter = write_rgb32b_to_rgb24;
971 break;
972
973 case B_RGBA32:
974 /*
975 // In theory it should be possible to write 4 color components
976 // to jp2, so it should be possible to have transparency.
977 // Unfortunetly libjasper does not agree with that
978 // For now i don't know how to modify it :(
979
980 out_color_components = 4;
981 converter = write_rgba32;
982 */
983 converter = write_rgb32_to_rgb24;
984 break;
985
986 case B_RGBA32_BIG:
987 /*
988 // In theory it should be possible to write 4 color components
989 // to jp2, so it should be possible to have transparency.
990 // Unfortunetly libjasper does not agree with that
991 // For now i don't know how to modify it :(
992
993 out_color_components = 4;
994 converter = write_rgba32b;
995 */
996 converter = write_rgb32b_to_rgb24;
997 break;
998
999 default:
1000 syslog(LOG_ERR, "Unknown color space.\n");
1001 return B_ERROR;
1002 }
1003
1004 jas_image_t* image;
1005 jas_stream_t* outs;
1006 jas_matrix_t* pixels[4];
1007 jas_image_cmptparm_t component_info[4];
1008
1009 if (jas_init())
1010 return B_ERROR;
1011
1012 if (!(outs = jas_stream_positionIOopen(out)))
1013 return B_ERROR;
1014
1015 int32 i = 0;
1016 for (i = 0; i < (long)out_color_components; i++) {
1017 (void) memset(component_info + i, 0, sizeof(jas_image_cmptparm_t));
1018 component_info[i].hstep = 1;
1019 component_info[i].vstep = 1;
1020 component_info[i].width = (unsigned int)width;
1021 component_info[i].height = (unsigned int)height;
1022 component_info[i].prec = (unsigned int)8;
1023 }
1024
1025 image = jas_image_create((short)out_color_components, component_info,
1026 out_color_space);
1027 if (image == (jas_image_t *)NULL)
1028 return Error(outs, NULL, NULL, 0, NULL, B_ERROR);
1029
1030 uchar *in_scanline = (uchar*) malloc(in_row_bytes);
1031 if (in_scanline == NULL)
1032 return Error(outs, image, NULL, 0, NULL, B_ERROR);
1033
1034 for (i = 0; i < (long)out_color_components; i++) {
1035 pixels[i] = jas_matrix_create(1, (unsigned int)width);
1036 if (pixels[i] == (jas_matrix_t *)NULL)
1037 return Error(outs, image, pixels, i+1, in_scanline, B_ERROR);
1038 }
1039
1040 int32 y = 0;
1041 for (y = 0; y < (long)height; y++) {
1042 err = in->Read(in_scanline, in_row_bytes);
1043 if (err < in_row_bytes) {
1044 return (err < B_OK) ? Error(outs, image, pixels,
1045 out_color_components, in_scanline, err)
1046 : Error(outs, image, pixels, out_color_components, in_scanline,
1047 B_ERROR);
1048 }
1049
1050 converter(pixels, in_scanline, width);
1051
1052 for (i = 0; i < (long)out_color_components; i++) {
1053 (void)jas_image_writecmpt(image, (short)i, 0, (unsigned int)y,
1054 (unsigned int)width, 1, pixels[i]);
1055 }
1056 }
1057
1058 char opts[16];
1059 sprintf(opts, "rate=%1f",
1060 (float)fSettings->SetGetInt32(JP2_SET_QUALITY) / 100.0);
1061
1062 if (jas_image_encode(image, outs, jas_image_strtofmt(
1063 fSettings->SetGetBool(JP2_SET_JPC) ?
1064 (char*)"jpc" : (char*)"jp2"), opts)) {
1065 return Error(outs, image, pixels,
1066 out_color_components, in_scanline, err);
1067 }
1068
1069 free(in_scanline);
1070
1071 for (i = 0; i < (long)out_color_components; i++)
1072 jas_matrix_destroy(pixels[i]);
1073
1074 jas_stream_close(outs);
1075 jas_image_destroy(image);
1076 jas_image_clearfmts();
1077
1078 return B_OK;
1079 }
1080
1081
1082 //! Decode the native format
1083 status_t
Decompress(BPositionIO * in,BPositionIO * out)1084 JP2Translator::Decompress(BPositionIO* in, BPositionIO* out)
1085 {
1086 using namespace conversion;
1087
1088 jas_image_t* image;
1089 jas_stream_t* ins;
1090 jas_matrix_t* pixels[4];
1091
1092 if (jas_init())
1093 return B_ERROR;
1094
1095 if (!(ins = jas_stream_positionIOopen(in)))
1096 return B_ERROR;
1097
1098 if (!(image = jas_image_decode(ins, -1, 0)))
1099 return Error(ins, NULL, NULL, 0, NULL, B_ERROR);
1100
1101 // Default color info
1102 color_space out_color_space;
1103 int out_color_components;
1104 int in_color_components = jas_image_numcmpts(image);
1105
1106 // Function pointer to read function
1107 // It MUST point to proper function
1108 void (*converter)(jas_matrix_t** pixels, uchar* outscanline,
1109 int width) = NULL;
1110
1111 switch (jas_clrspc_fam(jas_image_clrspc(image))) {
1112 case JAS_CLRSPC_FAM_RGB:
1113 out_color_components = 4;
1114 if (in_color_components == 3) {
1115 out_color_space = B_RGB32;
1116 converter = read_rgb24_to_rgb32;
1117 } else if (in_color_components == 4) {
1118 out_color_space = B_RGBA32;
1119 converter = read_rgba32;
1120 } else {
1121 syslog(LOG_ERR, "Other than RGB with 3 or 4 color "
1122 "components not implemented.\n");
1123 return Error(ins, image, NULL, 0, NULL, B_ERROR);
1124 }
1125 break;
1126 case JAS_CLRSPC_FAM_GRAY:
1127 if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) {
1128 out_color_space = B_RGB32;
1129 out_color_components = 4;
1130 converter = read_gray_to_rgb32;
1131 } else {
1132 out_color_space = B_GRAY8;
1133 out_color_components = 1;
1134 converter = read_gray;
1135 }
1136 break;
1137 case JAS_CLRSPC_FAM_YCBCR:
1138 syslog(LOG_ERR, "Color space YCBCR not implemented yet.\n");
1139 return Error(ins, image, NULL, 0, NULL, B_ERROR);
1140 break;
1141 case JAS_CLRSPC_UNKNOWN:
1142 default:
1143 syslog(LOG_ERR, "Color space unknown. \n");
1144 return Error(ins, image, NULL, 0, NULL, B_ERROR);
1145 break;
1146 }
1147
1148 float width = (float)jas_image_width(image);
1149 float height = (float)jas_image_height(image);
1150
1151 // Bytes count in one line of image (scanline)
1152 int64 out_row_bytes = (int32)width * out_color_components;
1153 // NOTE: things will go wrong if "out_row_bytes" wouldn't fit into 32 bits
1154
1155 // !!! Initialize this bounds rect to the size of your image
1156 BRect bounds(0, 0, width - 1, height - 1);
1157
1158
1159 // Fill out the B_TRANSLATOR_BITMAP's header
1160 TranslatorBitmap header;
1161 header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP);
1162 header.bounds.left = B_HOST_TO_BENDIAN_FLOAT(bounds.left);
1163 header.bounds.top = B_HOST_TO_BENDIAN_FLOAT(bounds.top);
1164 header.bounds.right = B_HOST_TO_BENDIAN_FLOAT(bounds.right);
1165 header.bounds.bottom = B_HOST_TO_BENDIAN_FLOAT(bounds.bottom);
1166 header.colors = (color_space)B_HOST_TO_BENDIAN_INT32(out_color_space);
1167 header.rowBytes = B_HOST_TO_BENDIAN_INT32(out_row_bytes);
1168 header.dataSize = B_HOST_TO_BENDIAN_INT32((int32)(out_row_bytes * height));
1169
1170 // Write out the header
1171 status_t err = out->Write(&header, sizeof(TranslatorBitmap));
1172 if (err < B_OK)
1173 return Error(ins, image, NULL, 0, NULL, err);
1174 if (err < (int)sizeof(TranslatorBitmap))
1175 return Error(ins, image, NULL, 0, NULL, B_ERROR);
1176
1177 uchar *out_scanline = (uchar*) malloc(out_row_bytes);
1178 if (out_scanline == NULL)
1179 return Error(ins, image, NULL, 0, NULL, B_ERROR);
1180
1181 int32 i = 0;
1182 for (i = 0; i < (long)in_color_components; i++) {
1183 pixels[i] = jas_matrix_create(1, (unsigned int)width);
1184 if (pixels[i] == (jas_matrix_t *)NULL)
1185 return Error(ins, image, pixels, i + 1, out_scanline, B_ERROR);
1186 }
1187
1188 int32 y = 0;
1189 for (y = 0; y < (long)height; y++) {
1190 for (i = 0; i < (long)in_color_components; i++) {
1191 (void)jas_image_readcmpt(image, (short)i, 0, (unsigned int)y,
1192 (unsigned int)width, 1, pixels[i]);
1193 }
1194
1195 converter(pixels, out_scanline, (int32)width);
1196
1197 err = out->Write(out_scanline, out_row_bytes);
1198 if (err < out_row_bytes) {
1199 return (err < B_OK) ? Error(ins, image, pixels, in_color_components,
1200 out_scanline, err)
1201 : Error(ins, image, pixels, in_color_components, out_scanline,
1202 B_ERROR);
1203 }
1204 }
1205
1206 free(out_scanline);
1207
1208 for (i = 0; i < (long)in_color_components; i++)
1209 jas_matrix_destroy(pixels[i]);
1210
1211 jas_stream_close(ins);
1212 jas_image_destroy(image);
1213 jas_image_clearfmts();
1214
1215 return B_OK;
1216 }
1217
1218
1219 /*! searches in both inputFormats & outputFormats */
1220 status_t
PopulateInfoFromFormat(translator_info * info,uint32 formatType,translator_id id)1221 JP2Translator::PopulateInfoFromFormat(translator_info* info,
1222 uint32 formatType, translator_id id)
1223 {
1224 int32 formatCount;
1225 const translation_format* formats = OutputFormats(&formatCount);
1226
1227 for (int i = 0; i <= 1; formats = InputFormats(&formatCount), i++) {
1228 if (PopulateInfoFromFormat(info, formatType,
1229 formats, formatCount) == B_OK) {
1230 info->translator = id;
1231 return B_OK;
1232 }
1233 }
1234
1235 return B_ERROR;
1236 }
1237
1238
1239 status_t
PopulateInfoFromFormat(translator_info * info,uint32 formatType,const translation_format * formats,int32 formatCount)1240 JP2Translator::PopulateInfoFromFormat(translator_info* info,
1241 uint32 formatType, const translation_format* formats, int32 formatCount)
1242 {
1243 for (int i = 0; i < formatCount; i++) {
1244 if (formats[i].type == formatType) {
1245 info->type = formatType;
1246 info->group = formats[i].group;
1247 info->quality = formats[i].quality;
1248 info->capability = formats[i].capability;
1249 if (strcmp(formats[i].name, B_TRANSLATOR_BITMAP_DESCRIPTION)
1250 == 0) {
1251 strlcpy(info->name,
1252 B_TRANSLATE(B_TRANSLATOR_BITMAP_DESCRIPTION),
1253 sizeof(info->name));
1254 } else {
1255 strlcpy(info->name, formats[i].name, sizeof(info->name));
1256 }
1257 strlcpy(info->MIME, formats[i].MIME, sizeof(info->MIME));
1258 return B_OK;
1259 }
1260 }
1261
1262 return B_ERROR;
1263 }
1264
1265
1266 /*!
1267 Frees jpeg alocated memory
1268 Returns given error (B_ERROR by default)
1269 */
1270 status_t
Error(jas_stream_t * stream,jas_image_t * image,jas_matrix_t ** pixels,int32 pixels_count,uchar * scanline,status_t error)1271 Error(jas_stream_t* stream, jas_image_t* image, jas_matrix_t** pixels,
1272 int32 pixels_count, uchar* scanline, status_t error)
1273 {
1274 if (pixels) {
1275 int32 i;
1276 for (i = 0; i < (long)pixels_count; i++) {
1277 if (pixels[i] != NULL)
1278 jas_matrix_destroy(pixels[i]);
1279 }
1280 }
1281 if (stream)
1282 jas_stream_close(stream);
1283 if (image)
1284 jas_image_destroy(image);
1285
1286 jas_image_clearfmts();
1287 free(scanline);
1288
1289 return error;
1290 }
1291
1292
1293 // #pragma mark -
1294
1295 BTranslator*
make_nth_translator(int32 n,image_id you,uint32 flags,...)1296 make_nth_translator(int32 n, image_id you, uint32 flags, ...)
1297 {
1298 if (!n)
1299 return new JP2Translator();
1300
1301 return NULL;
1302 }
1303
1304
1305 int
main()1306 main()
1307 {
1308 BApplication app("application/x-vnd.Haiku-JPEG2000Translator");
1309 JP2Translator* translator = new JP2Translator();
1310 if (LaunchTranslatorWindow(translator, sTranslatorName) == B_OK)
1311 app.Run();
1312
1313 return 0;
1314 }
1315
1316