Patch by Alex Wilson (yourpalal): Convert the JPEG2000 Translator to use the

BaseTranslator framework and layout management. Big coding style clean up, too.
Thanks a bunch, great work!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36466 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2010-04-25 11:12:20 +00:00
parent b98ef4f94b
commit 94a204f083
3 changed files with 353 additions and 427 deletions
@@ -33,8 +33,11 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "JPEG2000Translator.h" #include "JPEG2000Translator.h"
#include "jp2_cod.h" #include "jp2_cod.h"
#include "jpc_cs.h" #include "jpc_cs.h"
#include "TranslatorWindow.h"
#include <GroupLayoutBuilder.h>
#include <TabView.h> #include <TabView.h>
#include <TextView.h>
// Set these accordingly // Set these accordingly
@@ -47,9 +50,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define B_TRANSLATOR_BITMAP_MIME_STRING "image/x-be-bitmap" #define B_TRANSLATOR_BITMAP_MIME_STRING "image/x-be-bitmap"
#define B_TRANSLATOR_BITMAP_DESCRIPTION "Be Bitmap Format (JPEG2000Translator)" #define B_TRANSLATOR_BITMAP_DESCRIPTION "Be Bitmap Format (JPEG2000Translator)"
// Translation Kit required globals const char gTranslatorName[] = "JPEG2000 images";
char translatorName[] = "JPEG2000 images"; const char gTranslatorInfo[] = "©2002-2003, Shard\n"
char translatorInfo[] = "©2002-2003, Shard\n"
"©2005-2006, Haiku\n" "©2005-2006, Haiku\n"
"\n" "\n"
"Based on JasPer library:\n" "Based on JasPer library:\n"
@@ -61,96 +63,37 @@ char translatorInfo[] = "©2002-2003, Shard\n"
"ImageMagick's jp2 codec was used as \"tutorial\".\n" "ImageMagick's jp2 codec was used as \"tutorial\".\n"
" http://www.imagemagick.org/\n"; " http://www.imagemagick.org/\n";
int32 translatorVersion = 0x100; int32 gTranslatorVersion = B_TRANSLATION_MAKE_VERSION(1, 0, 0);
// Define the formats we know how to read translation_format gInputFormats[] = {
translation_format inputFormats[] = {
{ JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5, { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5,
JP2_MIME_STRING, JP2_DESCRIPTION }, JP2_MIME_STRING, JP2_DESCRIPTION },
{ B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5, { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5,
B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION }, B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION },
{},
}; };
const int gInputFormatCount =
sizeof(gInputFormats) / sizeof(translation_format);
// Define the formats we know how to write translation_format gOutputFormats[] = {
translation_format outputFormats[] = {
{ JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5, { JP2_FORMAT, B_TRANSLATOR_BITMAP, 0.5, 0.5,
JP2_MIME_STRING, JP2_DESCRIPTION }, JP2_MIME_STRING, JP2_DESCRIPTION },
{ B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5, { B_TRANSLATOR_BITMAP, B_TRANSLATOR_BITMAP, 0.5, 0.5,
B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION }, B_TRANSLATOR_BITMAP_MIME_STRING, B_TRANSLATOR_BITMAP_DESCRIPTION },
{},
}; };
const int gOutputFormatCount =
sizeof(gOutputFormats) / sizeof(translation_format);
//! Make settings to defaults TranSetting gSettings[] = {
void {JP2_SET_QUALITY, TRAN_SETTING_INT32, 25},
LoadDefaultSettings(jpeg_settings *settings) {JP2_SET_JPC, TRAN_SETTING_BOOL, false},
{ {JP2_SET_GRAY1_AS_B_RGB24, TRAN_SETTING_BOOL, false},
settings->Quality = 25; {JP2_SET_GRAY8_AS_B_RGB32, TRAN_SETTING_BOOL, true}
settings->JPC = false; };
settings->B_GRAY1_as_B_RGB24 = false; const int gSettingsCount = sizeof(gSettings) / sizeof(TranSetting) ;
settings->B_GRAY8_as_B_RGB32 = true;
}
//! Save settings to config file
void
SaveSettings(jpeg_settings *settings)
{
// Make path to settings file
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, true) != B_OK)
return;
path.Append(SETTINGS_FILE);
// Open settings file (create it if there's no file) and write settings
FILE *file = NULL;
if ((file = fopen(path.Path(), "wb+"))) {
fwrite(settings, sizeof(jpeg_settings), 1, file);
fclose(file);
}
}
/*!
Load settings from config file
If can't find it make them default and try to save
*/
void
LoadSettings(jpeg_settings *settings)
{
// Make path to settings file
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) {
LoadDefaultSettings(settings);
return;
}
path.Append(SETTINGS_FILE);
// Open settings file (create it if there's no file) and write settings
FILE *file = NULL;
if ((file = fopen(path.Path(), "rb"))) {
if (!fread(settings, sizeof(jpeg_settings), 1, file)) {
// settings struct has changed size
// Load default settings, and Save them
fclose(file);
LoadDefaultSettings(settings);
SaveSettings(settings);
} else
fclose(file);
} else if ((file = fopen(path.Path(), "wb+"))) {
LoadDefaultSettings(settings);
fwrite(settings, sizeof(jpeg_settings), 1, file);
fclose(file);
}
}
// #pragma mark - conversion routines
namespace conversion{
//! Make RGB32 scanline from *pixels[3] //! Make RGB32 scanline from *pixels[3]
inline void inline void
read_rgb24_to_rgb32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width) read_rgb24_to_rgb32(jas_matrix_t** pixels, jpr_uchar_t* scanline, int width)
@@ -306,9 +249,12 @@ write_rgb15_to_rgb24(jas_matrix_t **pixels, jpr_uchar_t *scanline, int width)
in_pixel = scanline[index] | (scanline[index+1] << 8); in_pixel = scanline[index] | (scanline[index+1] << 8);
index += 2; index += 2;
jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7) | (((in_pixel & 0x7c00)) >> 12)); jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7)
jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2) | (((in_pixel & 0x3e0)) >> 7)); | (((in_pixel & 0x7c00)) >> 12));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2)); jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2)
| (((in_pixel & 0x3e0)) >> 7));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
| (((in_pixel & 0x1f)) >> 2));
x++; x++;
} }
} }
@@ -328,9 +274,12 @@ write_rgb15b_to_rgb24(jas_matrix_t **pixels, jpr_uchar_t *scanline, int width)
in_pixel = scanline[index + 1] | (scanline[index] << 8); in_pixel = scanline[index + 1] | (scanline[index] << 8);
index += 2; index += 2;
jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7) | (((in_pixel & 0x7c00)) >> 12)); jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0x7c00)) >> 7)
jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2) | (((in_pixel & 0x3e0)) >> 7)); | (((in_pixel & 0x7c00)) >> 12));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2)); jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x3e0)) >> 2)
| (((in_pixel & 0x3e0)) >> 7));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
| (((in_pixel & 0x1f)) >> 2));
x++; x++;
} }
} }
@@ -350,9 +299,12 @@ write_rgb16_to_rgb24(jas_matrix_t **pixels, jpr_uchar_t *scanline, int width)
in_pixel = scanline[index] | (scanline[index+1] << 8); in_pixel = scanline[index] | (scanline[index+1] << 8);
index += 2; index += 2;
jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8) | (((in_pixel & 0x7c00)) >> 12)); jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8)
jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3) | (((in_pixel & 0x7e0)) >> 9)); | (((in_pixel & 0x7c00)) >> 12));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2)); jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3)
| (((in_pixel & 0x7e0)) >> 9));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
| (((in_pixel & 0x1f)) >> 2));
x++; x++;
} }
} }
@@ -372,9 +324,12 @@ write_rgb16b_to_rgb24(jas_matrix_t **pixels, jpr_uchar_t *scanline, int width)
in_pixel = scanline[index + 1] | (scanline[index] << 8); in_pixel = scanline[index + 1] | (scanline[index] << 8);
index += 2; index += 2;
jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8) | (((in_pixel & 0xf800)) >> 13)); jas_matrix_setv(pixels[0], x, (char)(((in_pixel & 0xf800)) >> 8)
jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3) | (((in_pixel & 0x7e0)) >> 9)); | (((in_pixel & 0xf800)) >> 13));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2)); jas_matrix_setv(pixels[1], x, (char)(((in_pixel & 0x7e0)) >> 3)
| (((in_pixel & 0x7e0)) >> 9));
jas_matrix_setv(pixels[2], x, (char)(((in_pixel & 0x1f)) << 3)
| (((in_pixel & 0x1f)) >> 2));
x++; x++;
} }
} }
@@ -495,6 +450,9 @@ write_rgba32b(jas_matrix_t **pixels, jpr_uchar_t *scanline, int width)
} }
}// end namespace conversion
// #pragma mark - jasper I/O // #pragma mark - jasper I/O
@@ -564,35 +522,15 @@ jas_stream_positionIOopen(BPositionIO *positionIO)
} }
// #pragma mark - SView
SView::SView(BRect frame, const char *name)
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
SetLowColor(ViewColor());
SetFont(be_plain_font);
}
void
SView::AttachedToWindow()
{
BView::AttachedToWindow();
ResizeTo(Parent()->Bounds().Width(), Parent()->Bounds().Height());
}
// #pragma mark - // #pragma mark -
SSlider::SSlider(BRect frame, const char *name, const char *label, SSlider::SSlider(const char* name, const char* label,
BMessage* message, int32 minValue, int32 maxValue, orientation posture, BMessage* message, int32 minValue, int32 maxValue, orientation posture,
thumb_style thumbType, uint32 resizingMode, uint32 flags) thumb_style thumbType, uint32 flags)
: BSlider(frame, name, label, message, minValue, maxValue, :
posture, thumbType, resizingMode, flags) BSlider(name, label, message, minValue, maxValue,
posture, thumbType, flags)
{ {
rgb_color barColor = { 0, 0, 229, 255 }; rgb_color barColor = { 0, 0, 229, 255 };
UseFillColor(true, &barColor); UseFillColor(true, &barColor);
@@ -608,44 +546,38 @@ SSlider::UpdateText() const
} }
//! BSlider::ResizeToPreferred + Resize width if it's too small to show label
// and status
void
SSlider::ResizeToPreferred()
{
int32 width = (int32)ceil(StringWidth(Label()) + StringWidth("9999"));
if (width < 230)
width = 230;
float w, h;
GetPreferredSize(&w, &h);
ResizeTo(width, h);
}
// #pragma mark - // #pragma mark -
TranslatorReadView::TranslatorReadView(BRect frame, const char *name, TranslatorReadView::TranslatorReadView(const char* name,
jpeg_settings *settings) TranslatorSettings* settings)
: SView(frame, name), :
BView(name, 0, new BGroupLayout(B_VERTICAL)),
fSettings(settings) fSettings(settings)
{ {
fGrayAsRGB32 = new BCheckBox(BRect(10, 10, 40, 40), "grayasrgb32", fGrayAsRGB32 = new BCheckBox("grayasrgb32", VIEW_LABEL_GRAYASRGB32,
VIEW_LABEL_GRAYASRGB32, new BMessage(VIEW_MSG_SET_GRAYASRGB32)); new BMessage(VIEW_MSG_SET_GRAYASRGB32));
fGrayAsRGB32->SetFont(be_plain_font); if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32))
if (fSettings->B_GRAY8_as_B_RGB32) fGrayAsRGB32->SetValue(B_CONTROL_ON);
fGrayAsRGB32->SetValue(1);
AddChild(fGrayAsRGB32); float padding = 10.0f;
fGrayAsRGB32->ResizeToPreferred(); AddChild(BGroupLayoutBuilder(B_VERTICAL)
.Add(fGrayAsRGB32)
.AddGlue()
.SetInsets(padding, padding, padding, padding)
);
}
TranslatorReadView::~TranslatorReadView()
{
fSettings->Release();
} }
void void
TranslatorReadView::AttachedToWindow() TranslatorReadView::AttachedToWindow()
{ {
SView::AttachedToWindow();
fGrayAsRGB32->SetTarget(this); fGrayAsRGB32->SetTarget(this);
} }
@@ -658,8 +590,9 @@ TranslatorReadView::MessageReceived(BMessage *message)
{ {
int32 value; int32 value;
if (message->FindInt32("be:value", &value) == B_OK) { if (message->FindInt32("be:value", &value) == B_OK) {
fSettings->B_GRAY8_as_B_RGB32 = value; bool boolValue = value;
SaveSettings(fSettings); fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32, &boolValue);
fSettings->SaveSettings();
} }
break; break;
} }
@@ -673,53 +606,49 @@ TranslatorReadView::MessageReceived(BMessage *message)
// #pragma mark - TranslatorWriteView // #pragma mark - TranslatorWriteView
TranslatorWriteView::TranslatorWriteView(BRect frame, const char *name, TranslatorWriteView::TranslatorWriteView(const char* name,
jpeg_settings *settings) TranslatorSettings* settings)
: SView(frame, name), :
BView(name, 0, new BGroupLayout(B_VERTICAL)),
fSettings(settings) fSettings(settings)
{ {
BRect rect(10, 10, 10, 40); fQualitySlider = new SSlider("quality", VIEW_LABEL_QUALITY,
fQualitySlider = new SSlider(rect, "quality", new BMessage(VIEW_MSG_SET_QUALITY), 0, 100);
VIEW_LABEL_QUALITY, new BMessage(VIEW_MSG_SET_QUALITY), 0, 100);
fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fQualitySlider->SetHashMarkCount(10); fQualitySlider->SetHashMarkCount(10);
fQualitySlider->SetLimitLabels("Low", "High"); fQualitySlider->SetLimitLabels("Low", "High");
fQualitySlider->SetFont(be_plain_font); fQualitySlider->SetValue(fSettings->SetGetInt32(JP2_SET_QUALITY));
fQualitySlider->SetValue(fSettings->Quality);
AddChild(fQualitySlider);
fQualitySlider->ResizeToPreferred();
rect.OffsetBy(0, fQualitySlider->Bounds().Height() + 10); fGrayAsRGB24 = new BCheckBox("gray1asrgb24", VIEW_LABEL_GRAY1ASRGB24,
fGrayAsRGB24 = new BCheckBox(rect, "gray1asrgb24",
VIEW_LABEL_GRAY1ASRGB24,
new BMessage(VIEW_MSG_SET_GRAY1ASRGB24)); new BMessage(VIEW_MSG_SET_GRAY1ASRGB24));
fGrayAsRGB24->SetFont(be_plain_font); if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24))
if (fSettings->B_GRAY1_as_B_RGB24) fGrayAsRGB24->SetValue(B_CONTROL_ON);
fGrayAsRGB24->SetValue(1);
AddChild(fGrayAsRGB24); fCodeStreamOnly = new BCheckBox("codestreamonly", VIEW_LABEL_JPC,
fGrayAsRGB24->ResizeToPreferred(); new BMessage(VIEW_MSG_SET_JPC));
if (fSettings->SetGetBool(JP2_SET_JPC))
fCodeStreamOnly->SetValue(B_CONTROL_ON);
rect.OffsetBy(0, fGrayAsRGB24->Bounds().Height() + 10); float padding = 10.0f;
AddChild(BGroupLayoutBuilder(B_VERTICAL, padding)
.Add(fQualitySlider)
.Add(fGrayAsRGB24)
.Add(fCodeStreamOnly)
.AddGlue()
.SetInsets(padding, padding, padding, padding)
);
}
fCodeStreamOnly = new BCheckBox(rect, "codestreamonly",
VIEW_LABEL_JPC, new BMessage(VIEW_MSG_SET_JPC));
fCodeStreamOnly->SetFont(be_plain_font);
if (fSettings->JPC)
fCodeStreamOnly->SetValue(1);
AddChild(fCodeStreamOnly); TranslatorWriteView::~TranslatorWriteView()
{
fCodeStreamOnly->ResizeToPreferred(); fSettings->Release();
} }
void void
TranslatorWriteView::AttachedToWindow() TranslatorWriteView::AttachedToWindow()
{ {
SView::AttachedToWindow();
fQualitySlider->SetTarget(this); fQualitySlider->SetTarget(this);
fGrayAsRGB24->SetTarget(this); fGrayAsRGB24->SetTarget(this);
fCodeStreamOnly->SetTarget(this); fCodeStreamOnly->SetTarget(this);
@@ -734,8 +663,8 @@ TranslatorWriteView::MessageReceived(BMessage *message)
{ {
int32 value; int32 value;
if (message->FindInt32("be:value", &value) == B_OK) { if (message->FindInt32("be:value", &value) == B_OK) {
fSettings->Quality = value; fSettings->SetGetInt32(JP2_SET_QUALITY, &value);
SaveSettings(fSettings); fSettings->SaveSettings();
} }
break; break;
} }
@@ -743,8 +672,9 @@ TranslatorWriteView::MessageReceived(BMessage *message)
{ {
int32 value; int32 value;
if (message->FindInt32("be:value", &value) == B_OK) { if (message->FindInt32("be:value", &value) == B_OK) {
fSettings->B_GRAY1_as_B_RGB24 = value; bool boolValue = value;
SaveSettings(fSettings); fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24, &boolValue);
fSettings->SaveSettings();
} }
break; break;
} }
@@ -752,8 +682,9 @@ TranslatorWriteView::MessageReceived(BMessage *message)
{ {
int32 value; int32 value;
if (message->FindInt32("be:value", &value) == B_OK) { if (message->FindInt32("be:value", &value) == B_OK) {
fSettings->JPC = value; bool boolValue = value;
SaveSettings(fSettings); fSettings->SetGetBool(JP2_SET_JPC, &boolValue);
fSettings->SaveSettings();
} }
break; break;
} }
@@ -767,131 +698,85 @@ TranslatorWriteView::MessageReceived(BMessage *message)
// #pragma mark - // #pragma mark -
TranslatorAboutView::TranslatorAboutView(BRect frame, const char *name) TranslatorAboutView::TranslatorAboutView(const char* name)
: SView(frame, name) :
BView(name, 0, new BGroupLayout(B_VERTICAL))
{ {
BStringView *title = new BStringView(BRect(10, 0, 10, 0), "Title", BAlignment labelAlignment = BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
translatorName); BStringView* title = new BStringView("Title", gTranslatorName);
title->SetFont(be_bold_font); title->SetFont(be_bold_font);
title->SetExplicitAlignment(labelAlignment);
AddChild(title);
title->ResizeToPreferred();
BRect rect = title->Bounds();
float space = title->StringWidth(" ");
char versionString[16]; char versionString[16];
sprintf(versionString, "v%d.%d.%d", (int)(translatorVersion >> 8), sprintf(versionString, "v%d.%d.%d", (int)(gTranslatorVersion >> 8),
(int)((translatorVersion >> 4) & 0xf), (int)(translatorVersion & 0xf)); (int)((gTranslatorVersion >> 4) & 0xf), (int)(gTranslatorVersion & 0xf));
BStringView *version = new BStringView(BRect(rect.right+space, rect.top, BStringView* version = new BStringView("Version", versionString);
rect.right+space, rect.top), "Version", versionString); version->SetExplicitAlignment(labelAlignment);
version->SetFont(be_plain_font);
version->SetFontSize(9);
// Make version be in the same line as title
version->ResizeToPreferred();
version->MoveBy(0, rect.bottom-version->Frame().bottom);
AddChild(version); BTextView* infoView = new BTextView("info");
infoView->SetText(gTranslatorInfo);
infoView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
infoView->MakeEditable(false);
version->ResizeToPreferred(); float padding = 10.0f;
AddChild(BGroupLayoutBuilder(B_VERTICAL, padding)
BRect stringFrame = title->Frame(); .Add(BGroupLayoutBuilder(B_HORIZONTAL, padding)
// Now for each line in translatorInfo add a BStringView .Add(title)
char* current = translatorInfo; .Add(version)
int32 index = 1; .AddGlue()
while (current != NULL && current[0]) { )
char text[128]; .Add(infoView)
char* newLine = strchr(current, '\n'); .SetInsets(padding, padding, padding, padding)
if (newLine == NULL) { );
strlcpy(text, current, sizeof(text));
current = NULL;
} else {
strlcpy(text, current, min_c((int32)sizeof(text),
newLine + 1 - current));
current = newLine + 1;
}
stringFrame.OffsetBy(0, stringFrame.Height() + 2);
BStringView* string = new BStringView(stringFrame, "copyright",
text);
if (index > 3)
string->SetFontSize(9);
AddChild(string);
string->ResizeToPreferred();
index++;
}
} }
// #pragma mark - // #pragma mark -
TranslatorView::TranslatorView(BRect frame, const char *name) TranslatorView::TranslatorView(const char* name, TranslatorSettings* settings)
: BTabView(frame, name) :
BTabView(name)
{ {
// Load settings to global settings struct AddTab(new TranslatorWriteView("Write", settings->Acquire()));
LoadSettings(&fSettings); AddTab(new TranslatorReadView("Read", settings->Acquire()));
AddTab(new TranslatorAboutView("About"));
BRect contentSize = ContainerView()->Bounds(); settings->Release();
SView *view = new TranslatorWriteView(contentSize, "Write",
&fSettings);
AddTab(view);
view = new TranslatorReadView(contentSize, "Read", &fSettings);
AddTab(view);
view = new TranslatorAboutView(contentSize, "About");
AddTab(view);
ResizeToPreferred(); BFont font;
GetFont(&font);
// Make TranslatorView resize itself with parent SetExplicitPreferredSize(
SetFlags(Flags() | B_FOLLOW_ALL); BSize((font.Size() * 380) / 12, (font.Size() * 250) / 12));
}
TranslatorView::~TranslatorView()
{
} }
// #pragma mark - // #pragma mark -
BView*
TranslatorWindow::TranslatorWindow(bool quitOnClose) JP2Translator::NewConfigView(TranslatorSettings* settings)
: BWindow(BRect(100, 100, 100, 100), "JPEG Settings", B_TITLED_WINDOW,
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
{ {
BRect extent(0, 0, 0, 0); BView* outView = new TranslatorView("TranslatorView", settings);
BView *config = NULL; return outView;
MakeConfig(NULL, &config, &extent);
AddChild(config);
ResizeTo(extent.Width(), extent.Height());
// Make application quit after this window close
if (quitOnClose)
SetFlags(Flags() | B_QUIT_ON_WINDOW_CLOSE);
} }
// #pragma mark - JP2Translator::JP2Translator()
:
BaseTranslator(gTranslatorName, gTranslatorInfo, gTranslatorVersion,
//! Hook to create and return our configuration view gInputFormats, gInputFormatCount,
status_t gOutputFormats, gOutputFormatCount, JP2_SETTINGS_FILE,
MakeConfig(BMessage *ioExtension, BView **outView, BRect *outExtent) gSettings, gSettingsCount, B_TRANSLATOR_BITMAP, JP2_FORMAT)
{ {
*outView = new TranslatorView(BRect(0, 0, 300, 250), "TranslatorView");
*outExtent = (*outView)->Frame();
return B_OK;
} }
//! Determine whether or not we can handle this data //! Determine whether or not we can handle this data
status_t status_t
Identify(BPositionIO *inSource, const translation_format *inFormat, JP2Translator::DerivedIdentify(BPositionIO* inSource,
BMessage *ioExtension, translator_info *outInfo, uint32 outType) const translation_format* inFormat, BMessage* ioExtension,
translator_info* outInfo, uint32 outType)
{ {
if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP) if ((outType != 0) && (outType != B_TRANSLATOR_BITMAP)
&& outType != JP2_FORMAT) && outType != JP2_FORMAT)
@@ -908,27 +793,16 @@ Identify(BPositionIO *inSource, const translation_format *inFormat,
if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic) if (B_BENDIAN_TO_HOST_INT32(((TranslatorBitmap *)header)->magic)
== B_TRANSLATOR_BITMAP) { == B_TRANSLATOR_BITMAP) {
outInfo->type = inputFormats[1].type; if (PopulateInfoFromFormat(outInfo, B_TRANSLATOR_BITMAP) != B_OK)
outInfo->translator = 0; return B_NO_TRANSLATOR;
outInfo->group = inputFormats[1].group;
outInfo->quality = inputFormats[1].quality;
outInfo->capability = inputFormats[1].capability;
strcpy(outInfo->name, inputFormats[1].name);
strcpy(outInfo->MIME, inputFormats[1].MIME);
} else { } else {
if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8) if ((((header[4] << 24) | (header[5] << 16) | (header[6] << 8)
| header[7]) == JP2_BOX_JP) // JP2 | header[7]) == JP2_BOX_JP) // JP2
|| (header[0] == (JPC_MS_SOC >> 8) && header[1] || (header[0] == (JPC_MS_SOC >> 8) && header[1]
== (JPC_MS_SOC & 0xff))) // JPC == (JPC_MS_SOC & 0xff))) // JPC
{ {
outInfo->type = inputFormats[0].type; if (PopulateInfoFromFormat(outInfo, JP2_FORMAT) != B_OK)
outInfo->translator = 0; return B_NO_TRANSLATOR;
outInfo->group = inputFormats[0].group;
outInfo->quality = inputFormats[0].quality;
outInfo->capability = inputFormats[0].capability;
strcpy(outInfo->name, inputFormats[0].name);
strcpy(outInfo->MIME, inputFormats[0].MIME);
return B_OK;
} else } else
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
} }
@@ -937,10 +811,10 @@ Identify(BPositionIO *inSource, const translation_format *inFormat,
} }
//! Arguably the most important method in the add-on
status_t status_t
Translate(BPositionIO *inSource, const translator_info *inInfo, JP2Translator::DerivedTranslate(BPositionIO* inSource,
BMessage *ioExtension, uint32 outType, BPositionIO *outDestination) const translator_info* inInfo, BMessage* ioExtension, uint32 outType,
BPositionIO* outDestination, int32 baseType)
{ {
// If no specific type was requested, convert to the interchange format // If no specific type was requested, convert to the interchange format
if (outType == 0) if (outType == 0)
@@ -960,7 +834,7 @@ Translate(BPositionIO *inSource, const translator_info *inInfo,
//! The user has requested the same format for input and output, so just copy //! The user has requested the same format for input and output, so just copy
status_t status_t
Copy(BPositionIO *in, BPositionIO *out) JP2Translator::Copy(BPositionIO* in, BPositionIO* out)
{ {
int block_size = 65536; int block_size = 65536;
void* buffer = malloc(block_size); void* buffer = malloc(block_size);
@@ -996,11 +870,9 @@ Copy(BPositionIO *in, BPositionIO *out)
//! Encode into the native format //! Encode into the native format
status_t status_t
Compress(BPositionIO *in, BPositionIO *out) JP2Translator::Compress(BPositionIO* in, BPositionIO* out)
{ {
// Load settings using namespace conversion;
jpeg_settings settings;
LoadSettings(&settings);
// Read info about bitmap // Read info about bitmap
TranslatorBitmap header; TranslatorBitmap header;
@@ -1033,7 +905,7 @@ Compress(BPositionIO *in, BPositionIO *out)
switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) { switch ((color_space)B_BENDIAN_TO_HOST_INT32(header.colors)) {
case B_GRAY1: case B_GRAY1:
if (settings.B_GRAY1_as_B_RGB24) { if (fSettings->SetGetBool(JP2_SET_GRAY1_AS_B_RGB24)) {
converter = write_gray1_to_rgb24; converter = write_gray1_to_rgb24;
} else { } else {
out_color_components = 1; out_color_components = 1;
@@ -1157,9 +1029,8 @@ Compress(BPositionIO *in, BPositionIO *out)
for (y = 0; y < (long)height; y++) { for (y = 0; y < (long)height; y++) {
err = in->Read(in_scanline, in_row_bytes); err = in->Read(in_scanline, in_row_bytes);
if (err < in_row_bytes) { if (err < in_row_bytes) {
return (err < B_OK) ? return (err < B_OK) ? Error(outs, image, pixels,
Error(outs, image, pixels, out_color_components, in_scanline, out_color_components, in_scanline, err)
err)
: Error(outs, image, pixels, out_color_components, in_scanline, : Error(outs, image, pixels, out_color_components, in_scanline,
B_ERROR); B_ERROR);
} }
@@ -1173,10 +1044,14 @@ Compress(BPositionIO *in, BPositionIO *out)
} }
char opts[16]; char opts[16];
sprintf(opts, "rate=%1f", (float)settings.Quality / 100.0); sprintf(opts, "rate=%1f",
if (jas_image_encode(image, outs, jas_image_strtofmt(settings.JPC ? (float)fSettings->SetGetInt32(JP2_SET_QUALITY) / 100.0);
if (jas_image_encode(image, outs, jas_image_strtofmt(
fSettings->SetGetBool(JP2_SET_JPC) ?
(char*)"jpc" : (char*)"jp2"), opts)) { (char*)"jpc" : (char*)"jp2"), opts)) {
return Error(outs, image, pixels, out_color_components, in_scanline, err); return Error(outs, image, pixels,
out_color_components, in_scanline, err);
} }
free(in_scanline); free(in_scanline);
@@ -1194,10 +1069,9 @@ Compress(BPositionIO *in, BPositionIO *out)
//! Decode the native format //! Decode the native format
status_t status_t
Decompress(BPositionIO *in, BPositionIO *out) JP2Translator::Decompress(BPositionIO* in, BPositionIO* out)
{ {
jpeg_settings settings; using namespace conversion;
LoadSettings(&settings);
jas_image_t* image; jas_image_t* image;
jas_stream_t* ins; jas_stream_t* ins;
@@ -1237,7 +1111,7 @@ Decompress(BPositionIO *in, BPositionIO *out)
} }
break; break;
case JAS_IMAGE_CS_GRAY: case JAS_IMAGE_CS_GRAY:
if (settings.B_GRAY8_as_B_RGB32) { if (fSettings->SetGetBool(JP2_SET_GRAY8_AS_B_RGB32)) {
out_color_space = B_RGB32; out_color_space = B_RGB32;
out_color_components = 4; out_color_components = 4;
converter = read_gray_to_rgb32; converter = read_gray_to_rgb32;
@@ -1268,6 +1142,7 @@ Decompress(BPositionIO *in, BPositionIO *out)
// !!! Initialize this bounds rect to the size of your image // !!! Initialize this bounds rect to the size of your image
BRect bounds(0, 0, width - 1, height - 1); BRect bounds(0, 0, width - 1, height - 1);
// Fill out the B_TRANSLATOR_BITMAP's header // Fill out the B_TRANSLATOR_BITMAP's header
TranslatorBitmap header; TranslatorBitmap header;
header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP); header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP);
@@ -1308,9 +1183,8 @@ Decompress(BPositionIO *in, BPositionIO *out)
err = out->Write(out_scanline, out_row_bytes); err = out->Write(out_scanline, out_row_bytes);
if (err < out_row_bytes) { if (err < out_row_bytes) {
return (err < B_OK) ? return (err < B_OK) ? Error(ins, image, pixels, in_color_components,
Error(ins, image, pixels, in_color_components, out_scanline, out_scanline, err)
err)
: Error(ins, image, pixels, in_color_components, out_scanline, : Error(ins, image, pixels, in_color_components, out_scanline,
B_ERROR); B_ERROR);
} }
@@ -1329,6 +1203,46 @@ Decompress(BPositionIO *in, BPositionIO *out)
} }
/*! searches in both inputFormats & outputFormats */
status_t
JP2Translator::PopulateInfoFromFormat(translator_info* info,
uint32 formatType, translator_id id)
{
int32 formatCount;
const translation_format* formats = OutputFormats(&formatCount);
for (int i = 0; i <= 1; formats = InputFormats(&formatCount), i++) {
if (PopulateInfoFromFormat(info, formatType,
formats, formatCount) == B_OK) {
info->translator = id;
return B_OK;
}
}
return B_ERROR;
}
status_t
JP2Translator::PopulateInfoFromFormat(translator_info* info,
uint32 formatType, const translation_format* formats, int32 formatCount)
{
for (int i = 0; i < formatCount; i++) {
if (formats[i].type == formatType) {
info->type = formatType;
info->group = formats[i].group;
info->quality = formats[i].quality;
info->capability = formats[i].capability;
strcpy(info->name, formats[i].name);
strcpy(info->MIME, formats[i].MIME);
return B_OK;
}
}
return B_ERROR;
}
/*! /*!
Frees jpeg alocated memory Frees jpeg alocated memory
Returns given error (B_ERROR by default) Returns given error (B_ERROR by default)
@@ -1358,16 +1272,24 @@ Error(jas_stream_t *stream, jas_image_t *image, jas_matrix_t **pixels,
// #pragma mark - // #pragma mark -
BTranslator*
make_nth_translator(int32 n, image_id you, uint32 flags, ...)
{
if (!n)
return new JP2Translator();
return NULL;
}
int int
main() main()
{ {
BApplication app("application/x-vnd.Haiku-JPEG2000Translator"); BApplication app("application/x-vnd.Haiku-JPEG2000Translator");
JP2Translator* translator = new JP2Translator();
TranslatorWindow *window = new TranslatorWindow(); if (LaunchTranslatorWindow(translator, gTranslatorName) == B_OK)
window->Show();
app.Run(); app.Run();
return 0; return 0;
} }
@@ -48,11 +48,17 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "BaseTranslator.h"
#include "libjasper/jasper.h" #include "libjasper/jasper.h"
// Settings // Settings
#define SETTINGS_FILE "JPEG2000Translator" #define JP2_SETTINGS_FILE "JPEG2000Translator"
#define JP2_SET_QUALITY "quality"
#define JP2_SET_GRAY1_AS_B_RGB24 "24 from gray1"
#define JP2_SET_GRAY8_AS_B_RGB32 "32 from gray8"
#define JP2_SET_JPC "jpc"
// View messages // View messages
#define VIEW_MSG_SET_QUALITY 'JSCQ' #define VIEW_MSG_SET_QUALITY 'JSCQ'
@@ -62,21 +68,11 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// View labels // View labels
#define VIEW_LABEL_QUALITY "Output quality" #define VIEW_LABEL_QUALITY "Output quality"
#define VIEW_LABEL_GRAY1ASRGB24 "Write black-and-white images as RGB24"
#define VIEW_LABEL_JPC "Output only codestream (.jpc)" #define VIEW_LABEL_JPC "Output only codestream (.jpc)"
#define VIEW_LABEL_GRAY1ASRGB24 "Write black-and-white images as RGB24"
#define VIEW_LABEL_GRAYASRGB32 "Read greyscale images as RGB32" #define VIEW_LABEL_GRAYASRGB32 "Read greyscale images as RGB32"
//! Settings storage structure
struct jpeg_settings {
// compression
jpr_uchar_t Quality; // default: 25
bool JPC; // default: false // compress to JPC or JP2?
bool B_GRAY1_as_B_RGB24; // default: false // copress gray 1 as rgb24 or grayscale?
// decompression
bool B_GRAY8_as_B_RGB32; // default: true
};
/*! /*!
Slider used in TranslatorView Slider used in TranslatorView
@@ -84,80 +80,85 @@ struct jpeg_settings {
*/ */
class SSlider : public BSlider { class SSlider : public BSlider {
public: public:
SSlider(BRect frame, const char *name, const char *label, SSlider(const char* name, const char* label,
BMessage* message, int32 minValue, int32 maxValue, BMessage* message, int32 minValue, int32 maxValue,
orientation posture = B_HORIZONTAL, orientation posture = B_HORIZONTAL,
thumb_style thumbType = B_BLOCK_THUMB, thumb_style thumbType = B_BLOCK_THUMB,
uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
uint32 flags = B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS); uint32 flags = B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS);
const char* UpdateText() const; const char* UpdateText() const;
void ResizeToPreferred();
private: private:
mutable char fStatusLabel[12]; mutable char fStatusLabel[12];
}; };
//! Basic view class with resizing to needed size
class SView : public BView {
public:
SView(BRect rect, const char* name);
virtual void AttachedToWindow();
};
//! Configuration view for reading settings //! Configuration view for reading settings
class TranslatorReadView : public SView { class TranslatorReadView : public BView {
public: public:
TranslatorReadView(BRect rect, const char* name, jpeg_settings* settings); TranslatorReadView(const char* name, TranslatorSettings* settings);
~TranslatorReadView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
private: private:
jpeg_settings* fSettings; TranslatorSettings* fSettings;
BCheckBox* fGrayAsRGB32; BCheckBox* fGrayAsRGB32;
}; };
//! Configuration view for writing settings //! Configuration view for writing settings
class TranslatorWriteView : public SView { class TranslatorWriteView : public BView {
public: public:
TranslatorWriteView(BRect rect, const char* name, jpeg_settings* settings); TranslatorWriteView(const char* name, TranslatorSettings* settings);
~TranslatorWriteView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
private: private:
jpeg_settings* fSettings; TranslatorSettings* fSettings;
SSlider* fQualitySlider; SSlider* fQualitySlider;
BCheckBox* fGrayAsRGB24; BCheckBox* fGrayAsRGB24;
BCheckBox* fCodeStreamOnly; BCheckBox* fCodeStreamOnly;
}; };
class TranslatorAboutView : public SView { class TranslatorAboutView : public BView {
public: public:
TranslatorAboutView(BRect rect, const char* name); TranslatorAboutView(const char* name);
}; };
//! Configuration view //! Configuration view
class TranslatorView : public BTabView { class TranslatorView : public BTabView {
public: public:
TranslatorView(BRect rect, const char *name); TranslatorView(const char* name, TranslatorSettings* settings);
virtual ~TranslatorView(); };
class JP2Translator : public BaseTranslator {
public:
JP2Translator();
virtual status_t DerivedIdentify(BPositionIO* inSource,
const translation_format* inFormat, BMessage* ioExtension,
translator_info* outInfo, uint32 outType);
virtual status_t DerivedTranslate(BPositionIO* inSource,
const translator_info* inInfo, BMessage* ioExtension,
uint32 outType, BPositionIO* outDestination, int32 baseType);
virtual BView* NewConfigView(TranslatorSettings* settings);
private: private:
jpeg_settings fSettings;
};
//! Window used for configuration
class TranslatorWindow : public BWindow {
public:
TranslatorWindow(bool quitOnClose = true);
};
// Main functions of translator :)
status_t Copy(BPositionIO* in, BPositionIO* out); status_t Copy(BPositionIO* in, BPositionIO* out);
status_t Compress(BPositionIO* in, BPositionIO* out); status_t Compress(BPositionIO* in, BPositionIO* out);
status_t Decompress(BPositionIO* in, BPositionIO* out); status_t Decompress(BPositionIO* in, BPositionIO* out);
status_t Error(jas_stream_t *stream, jas_image_t *image, jas_matrix_t **pixels, int32 pixels_count, jpr_uchar_t *scanline, status_t error = B_ERROR);
status_t PopulateInfoFromFormat(translator_info* info,
uint32 formatType, translator_id id = 0);
status_t PopulateInfoFromFormat(translator_info* info,
uint32 formatType, const translation_format* formats,
int32 formatCount);
};
status_t Error(jas_stream_t* stream, jas_image_t* image, jas_matrix_t** pixels,
int32 pixels_count, jpr_uchar_t* scanline, status_t error = B_ERROR);
#endif // _JP2TRANSLATOR_H_ #endif // _JP2TRANSLATOR_H_
+4 -1
View File
@@ -4,6 +4,9 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirSysHdrs [ FDirName $(SUBDIR) libjasper ] ; SubDirSysHdrs [ FDirName $(SUBDIR) libjasper ] ;
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ;
#for BaseTranslator.h and friends
# Exclude unwanted formats # Exclude unwanted formats
CCFLAGS += -DEXCLUDE_MIF_SUPPORT CCFLAGS += -DEXCLUDE_MIF_SUPPORT
-DEXCLUDE_PNM_SUPPORT -DEXCLUDE_PNM_SUPPORT
@@ -66,7 +69,7 @@ Translator JPEG2000Translator :
$(jasper_files) $(jasper_files)
: be translation $(TARGET_LIBSUPC++) : be translation libtranslatorsutils.a $(TARGET_LIBSUPC++)
: true : true
; ;