xref: /haiku/src/add-ons/translators/jpeg/JPEGTranslator.h (revision 9949213a25979d177b420bc71891c2bff02a331d)
1*9949213aSStephan Aßmus /*
2*9949213aSStephan Aßmus 
3*9949213aSStephan Aßmus Copyright (c) 2002-2003, Marcin 'Shard' Konicki
4*9949213aSStephan Aßmus All rights reserved.
5*9949213aSStephan Aßmus 
6*9949213aSStephan Aßmus Redistribution and use in source and binary forms, with or without
7*9949213aSStephan Aßmus modification, are permitted provided that the following conditions are met:
8*9949213aSStephan Aßmus 
9*9949213aSStephan Aßmus     * Redistributions of source code must retain the above copyright notice,
10*9949213aSStephan Aßmus       this list of conditions and the following disclaimer.
11*9949213aSStephan Aßmus     * Redistributions in binary form must reproduce the above copyright notice,
12*9949213aSStephan Aßmus       this list of conditions and the following disclaimer in the documentation and/or
13*9949213aSStephan Aßmus       other materials provided with the distribution.
14*9949213aSStephan Aßmus     * Name "Marcin Konicki", "Shard" or any combination of them,
15*9949213aSStephan Aßmus       must not be used to endorse or promote products derived from this
16*9949213aSStephan Aßmus       software without specific prior written permission from Marcin Konicki.
17*9949213aSStephan Aßmus 
18*9949213aSStephan Aßmus THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19*9949213aSStephan Aßmus ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20*9949213aSStephan Aßmus THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*9949213aSStephan Aßmus ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22*9949213aSStephan Aßmus BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23*9949213aSStephan Aßmus OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24*9949213aSStephan Aßmus PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25*9949213aSStephan Aßmus OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26*9949213aSStephan Aßmus WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27*9949213aSStephan Aßmus OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28*9949213aSStephan Aßmus EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*9949213aSStephan Aßmus 
30*9949213aSStephan Aßmus */
31*9949213aSStephan Aßmus 
32*9949213aSStephan Aßmus #ifndef _JPEGTRANSLATOR_H_
33*9949213aSStephan Aßmus #define _JPEGTRANSLATOR_H_
34*9949213aSStephan Aßmus 
35*9949213aSStephan Aßmus 
36*9949213aSStephan Aßmus //----------------------------------------------------------------------------
37*9949213aSStephan Aßmus //
38*9949213aSStephan Aßmus //	Include
39*9949213aSStephan Aßmus //
40*9949213aSStephan Aßmus //----------------------------------------------------------------------------
41*9949213aSStephan Aßmus 
42*9949213aSStephan Aßmus #include <Alert.h>
43*9949213aSStephan Aßmus #include <Application.h>
44*9949213aSStephan Aßmus #include <CheckBox.h>
45*9949213aSStephan Aßmus #include <FindDirectory.h>
46*9949213aSStephan Aßmus #include <Path.h>
47*9949213aSStephan Aßmus #include <Slider.h>
48*9949213aSStephan Aßmus #include <StringView.h>
49*9949213aSStephan Aßmus #include <TranslationKit.h>
50*9949213aSStephan Aßmus #include <TranslatorAddOn.h>
51*9949213aSStephan Aßmus 
52*9949213aSStephan Aßmus #include <stdio.h>
53*9949213aSStephan Aßmus #include <stdlib.h>
54*9949213aSStephan Aßmus #include <string.h>
55*9949213aSStephan Aßmus 
56*9949213aSStephan Aßmus #include <jpeglib.h>
57*9949213aSStephan Aßmus 
58*9949213aSStephan Aßmus 
59*9949213aSStephan Aßmus //----------------------------------------------------------------------------
60*9949213aSStephan Aßmus //
61*9949213aSStephan Aßmus //	Define & Global variables declaration
62*9949213aSStephan Aßmus //
63*9949213aSStephan Aßmus //----------------------------------------------------------------------------
64*9949213aSStephan Aßmus 
65*9949213aSStephan Aßmus // Settings
66*9949213aSStephan Aßmus #define SETTINGS_FILE	"OpenJPEGTranslator"
67*9949213aSStephan Aßmus #define SETTINGS_PATH	"/boot/home/config/settings"
68*9949213aSStephan Aßmus 
69*9949213aSStephan Aßmus // View messages
70*9949213aSStephan Aßmus #define VIEW_MSG_SET_QUALITY 'JSCQ'
71*9949213aSStephan Aßmus #define VIEW_MSG_SET_SMOOTHING 'JSCS'
72*9949213aSStephan Aßmus #define VIEW_MSG_SET_PROGRESSIVE 'JSCP'
73*9949213aSStephan Aßmus #define VIEW_MSG_SET_OPTIMIZECOLORS 'JSBQ'
74*9949213aSStephan Aßmus #define	VIEW_MSG_SET_SMALLERFILE 'JSSF'
75*9949213aSStephan Aßmus #define	VIEW_MSG_SET_GRAY1ASRGB24 'JSGR'
76*9949213aSStephan Aßmus #define	VIEW_MSG_SET_ALWAYSRGB32 'JSAC'
77*9949213aSStephan Aßmus #define	VIEW_MSG_SET_PHOTOSHOPCMYK 'JSPC'
78*9949213aSStephan Aßmus #define	VIEW_MSG_SET_SHOWREADERRORBOX 'JSEB'
79*9949213aSStephan Aßmus 
80*9949213aSStephan Aßmus // View labels
81*9949213aSStephan Aßmus #define VIEW_LABEL_QUALITY "Output quality"
82*9949213aSStephan Aßmus #define VIEW_LABEL_SMOOTHING "Output smoothing strength"
83*9949213aSStephan Aßmus #define VIEW_LABEL_PROGRESSIVE "Use progressive compression"
84*9949213aSStephan Aßmus #define VIEW_LABEL_OPTIMIZECOLORS "Prevent colors 'washing out'"
85*9949213aSStephan Aßmus #define	VIEW_LABEL_SMALLERFILE "Make file smaller (sligthtly worse quality)"
86*9949213aSStephan Aßmus #define	VIEW_LABEL_GRAY1ASRGB24 "Write Black&White images as RGB24"
87*9949213aSStephan Aßmus #define	VIEW_LABEL_ALWAYSRGB32 "Read Greyscale images as RGB32"
88*9949213aSStephan Aßmus #define	VIEW_LABEL_PHOTOSHOPCMYK "Use CMYK code with 0 for 100% ink coverage"
89*9949213aSStephan Aßmus #define	VIEW_LABEL_SHOWREADERRORBOX "Show warning messages"
90*9949213aSStephan Aßmus 
91*9949213aSStephan Aßmus // This will be used true if Settings are running, else false
92*9949213aSStephan Aßmus extern bool AreSettingsRunning;
93*9949213aSStephan Aßmus 
94*9949213aSStephan Aßmus 
95*9949213aSStephan Aßmus //----------------------------------------------------------------------------
96*9949213aSStephan Aßmus //
97*9949213aSStephan Aßmus //	Classes
98*9949213aSStephan Aßmus //
99*9949213aSStephan Aßmus //----------------------------------------------------------------------------
100*9949213aSStephan Aßmus 
101*9949213aSStephan Aßmus //---------------------------------------------------
102*9949213aSStephan Aßmus //	Settings storage structure
103*9949213aSStephan Aßmus //---------------------------------------------------
104*9949213aSStephan Aßmus struct SETTINGS
105*9949213aSStephan Aßmus {
106*9949213aSStephan Aßmus 	// compression
107*9949213aSStephan Aßmus 	uchar	Smoothing;			// default: 0
108*9949213aSStephan Aßmus 	uchar	Quality;			// default: 95
109*9949213aSStephan Aßmus 	bool	Progressive;		// default: true
110*9949213aSStephan Aßmus 	bool	OptimizeColors;		// default: true
111*9949213aSStephan Aßmus 	bool	SmallerFile;		// default: false	only used if (OptimizeColors == true)
112*9949213aSStephan Aßmus 	bool	B_GRAY1_as_B_RGB24;	// default: false	if false gray1 converted to gray8, else to rgb24
113*9949213aSStephan Aßmus 	// decompression
114*9949213aSStephan Aßmus 	bool	Always_B_RGB32;		// default: true
115*9949213aSStephan Aßmus 	bool	PhotoshopCMYK;		// default: true
116*9949213aSStephan Aßmus 	bool	ShowReadWarningBox;	// default: true
117*9949213aSStephan Aßmus };
118*9949213aSStephan Aßmus 
119*9949213aSStephan Aßmus //---------------------------------------------------
120*9949213aSStephan Aßmus //	Slider used in TranslatorView
121*9949213aSStephan Aßmus //	With status showing actual value
122*9949213aSStephan Aßmus //---------------------------------------------------
123*9949213aSStephan Aßmus class SSlider : public BSlider
124*9949213aSStephan Aßmus {
125*9949213aSStephan Aßmus 	public:
126*9949213aSStephan Aßmus 							SSlider(BRect frame, const char *name, const char *label, BMessage *message, int32 minValue, int32 maxValue, orientation posture = B_HORIZONTAL, thumb_style thumbType = B_BLOCK_THUMB, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, uint32 flags = B_NAVIGABLE | B_WILL_DRAW | B_FRAME_EVENTS);
127*9949213aSStephan Aßmus 		char*				UpdateText() const;
128*9949213aSStephan Aßmus 		void				ResizeToPreferred();
129*9949213aSStephan Aßmus 
130*9949213aSStephan Aßmus 	private:
131*9949213aSStephan Aßmus 		char				statusLabel[12];
132*9949213aSStephan Aßmus };
133*9949213aSStephan Aßmus 
134*9949213aSStephan Aßmus 
135*9949213aSStephan Aßmus //---------------------------------------------------
136*9949213aSStephan Aßmus //	Basic view class with resizing to needed size
137*9949213aSStephan Aßmus //---------------------------------------------------
138*9949213aSStephan Aßmus class SView : public BView
139*9949213aSStephan Aßmus {
140*9949213aSStephan Aßmus 	public:
141*9949213aSStephan Aßmus 							SView(const char *name, float x = 0, float y = 0)
142*9949213aSStephan Aßmus 								:BView( BRect(x,y,x,y), name, B_FOLLOW_NONE, B_WILL_DRAW)
143*9949213aSStephan Aßmus 								{
144*9949213aSStephan Aßmus 									preferredWidth = 0;
145*9949213aSStephan Aßmus 									preferredHeight = 0;
146*9949213aSStephan Aßmus 									SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR));
147*9949213aSStephan Aßmus 									SetFont(be_plain_font);
148*9949213aSStephan Aßmus 								};
149*9949213aSStephan Aßmus 		void				GetPreferredSize(float *width, float *height)
150*9949213aSStephan Aßmus 								{
151*9949213aSStephan Aßmus 									*width = preferredWidth;
152*9949213aSStephan Aßmus 									*height = preferredHeight;
153*9949213aSStephan Aßmus 								}
154*9949213aSStephan Aßmus 		inline float		GetPreferredWidth() { return preferredWidth; };
155*9949213aSStephan Aßmus 		inline float		GetPreferredHeight() { return preferredHeight; };
156*9949213aSStephan Aßmus 		inline void			ResizePreferredBy(float width, float height) { preferredWidth += width; preferredHeight += height; };
157*9949213aSStephan Aßmus 		inline void			ResizeToPreferred() { ResizeTo(preferredWidth, preferredHeight); };
158*9949213aSStephan Aßmus 		void				AddChild(BView *child, BView *before = NULL)
159*9949213aSStephan Aßmus 								{
160*9949213aSStephan Aßmus 									BView::AddChild(child, before);
161*9949213aSStephan Aßmus 									child->ResizeToPreferred();
162*9949213aSStephan Aßmus 									BRect frame = child->Frame();
163*9949213aSStephan Aßmus 									if (frame.right > preferredWidth)
164*9949213aSStephan Aßmus 										preferredWidth = frame.right;
165*9949213aSStephan Aßmus 									if (frame.bottom > preferredHeight)
166*9949213aSStephan Aßmus 										preferredHeight = frame.bottom;
167*9949213aSStephan Aßmus 								}
168*9949213aSStephan Aßmus 
169*9949213aSStephan Aßmus 	private:
170*9949213aSStephan Aßmus 		float				preferredWidth;
171*9949213aSStephan Aßmus 		float				preferredHeight;
172*9949213aSStephan Aßmus };
173*9949213aSStephan Aßmus 
174*9949213aSStephan Aßmus //---------------------------------------------------
175*9949213aSStephan Aßmus //	Configuration view for reading settings
176*9949213aSStephan Aßmus //---------------------------------------------------
177*9949213aSStephan Aßmus class TranslatorReadView : public SView
178*9949213aSStephan Aßmus {
179*9949213aSStephan Aßmus 	public:
180*9949213aSStephan Aßmus 							TranslatorReadView(const char *name, SETTINGS *settings, float x = 0, float y = 0);
181*9949213aSStephan Aßmus 		void				AttachedToWindow();
182*9949213aSStephan Aßmus 		void				MessageReceived(BMessage *message);
183*9949213aSStephan Aßmus 
184*9949213aSStephan Aßmus 	private:
185*9949213aSStephan Aßmus 		SETTINGS			*Settings;
186*9949213aSStephan Aßmus 		BCheckBox			*alwaysrgb32;
187*9949213aSStephan Aßmus 		BCheckBox			*photoshopCMYK;
188*9949213aSStephan Aßmus 		BCheckBox			*showerrorbox;
189*9949213aSStephan Aßmus };
190*9949213aSStephan Aßmus 
191*9949213aSStephan Aßmus //---------------------------------------------------
192*9949213aSStephan Aßmus //	Configuration view for writing settings
193*9949213aSStephan Aßmus //---------------------------------------------------
194*9949213aSStephan Aßmus class TranslatorWriteView : public SView
195*9949213aSStephan Aßmus {
196*9949213aSStephan Aßmus 	public:
197*9949213aSStephan Aßmus 							TranslatorWriteView(const char *name, SETTINGS *settings, float x = 0, float y = 0);
198*9949213aSStephan Aßmus 		void				AttachedToWindow();
199*9949213aSStephan Aßmus 		void				MessageReceived(BMessage *message);
200*9949213aSStephan Aßmus 
201*9949213aSStephan Aßmus 	private:
202*9949213aSStephan Aßmus 		SETTINGS			*Settings;
203*9949213aSStephan Aßmus 		SSlider				*quality;
204*9949213aSStephan Aßmus 		SSlider				*smoothing;
205*9949213aSStephan Aßmus 		BCheckBox			*progress;
206*9949213aSStephan Aßmus 		BCheckBox			*optimizecolors;
207*9949213aSStephan Aßmus 		BCheckBox			*smallerfile;
208*9949213aSStephan Aßmus 		BCheckBox			*gray1asrgb24;
209*9949213aSStephan Aßmus };
210*9949213aSStephan Aßmus 
211*9949213aSStephan Aßmus //---------------------------------------------------
212*9949213aSStephan Aßmus //	About view
213*9949213aSStephan Aßmus //---------------------------------------------------
214*9949213aSStephan Aßmus class TranslatorAboutView : public SView
215*9949213aSStephan Aßmus {
216*9949213aSStephan Aßmus 	public:
217*9949213aSStephan Aßmus 							TranslatorAboutView(const char *name, float x = 0, float y = 0);
218*9949213aSStephan Aßmus };
219*9949213aSStephan Aßmus 
220*9949213aSStephan Aßmus //---------------------------------------------------
221*9949213aSStephan Aßmus //	Configuration view
222*9949213aSStephan Aßmus //---------------------------------------------------
223*9949213aSStephan Aßmus class TranslatorView : public SView
224*9949213aSStephan Aßmus {
225*9949213aSStephan Aßmus 	public:
226*9949213aSStephan Aßmus 							TranslatorView(const char *name);
227*9949213aSStephan Aßmus 							~TranslatorView() { AreSettingsRunning = false; };
228*9949213aSStephan Aßmus 		void				AttachedToWindow();
229*9949213aSStephan Aßmus 		void				Draw(BRect updateRect);
230*9949213aSStephan Aßmus 		void				MouseDown(BPoint where);
231*9949213aSStephan Aßmus 
232*9949213aSStephan Aßmus 	private:
233*9949213aSStephan Aßmus 		SETTINGS			Settings;
234*9949213aSStephan Aßmus 		int32				tabWidth;
235*9949213aSStephan Aßmus 		int32				tabHeight;
236*9949213aSStephan Aßmus 		int32				activeChild;
237*9949213aSStephan Aßmus };
238*9949213aSStephan Aßmus 
239*9949213aSStephan Aßmus //---------------------------------------------------
240*9949213aSStephan Aßmus //	Window used for configuration
241*9949213aSStephan Aßmus //---------------------------------------------------
242*9949213aSStephan Aßmus class TranslatorWindow : public BWindow
243*9949213aSStephan Aßmus {
244*9949213aSStephan Aßmus 	public:
245*9949213aSStephan Aßmus 							TranslatorWindow(bool quit_on_close = true);
246*9949213aSStephan Aßmus };
247*9949213aSStephan Aßmus 
248*9949213aSStephan Aßmus 
249*9949213aSStephan Aßmus //----------------------------------------------------------------------------
250*9949213aSStephan Aßmus //
251*9949213aSStephan Aßmus //	Functions :: Settings
252*9949213aSStephan Aßmus //
253*9949213aSStephan Aßmus //----------------------------------------------------------------------------
254*9949213aSStephan Aßmus 
255*9949213aSStephan Aßmus //---------------------------------------------------
256*9949213aSStephan Aßmus //	Make Settings to defaults
257*9949213aSStephan Aßmus //---------------------------------------------------
258*9949213aSStephan Aßmus inline void
259*9949213aSStephan Aßmus LoadDefaultSettings(SETTINGS *Settings)
260*9949213aSStephan Aßmus {
261*9949213aSStephan Aßmus 	Settings->Smoothing = 0;
262*9949213aSStephan Aßmus 	Settings->Quality = 95;
263*9949213aSStephan Aßmus 	Settings->Progressive = true;
264*9949213aSStephan Aßmus 	Settings->OptimizeColors = true;
265*9949213aSStephan Aßmus 	Settings->SmallerFile = false;
266*9949213aSStephan Aßmus 	Settings->B_GRAY1_as_B_RGB24 = false;
267*9949213aSStephan Aßmus 	Settings->Always_B_RGB32 = true;
268*9949213aSStephan Aßmus 	Settings->PhotoshopCMYK = true;
269*9949213aSStephan Aßmus 	Settings->ShowReadWarningBox = true;
270*9949213aSStephan Aßmus }
271*9949213aSStephan Aßmus 
272*9949213aSStephan Aßmus //---------------------------------------------------
273*9949213aSStephan Aßmus //	Save Settings to config file
274*9949213aSStephan Aßmus //---------------------------------------------------
275*9949213aSStephan Aßmus inline void
276*9949213aSStephan Aßmus SaveSettings(SETTINGS *Settings)
277*9949213aSStephan Aßmus {
278*9949213aSStephan Aßmus 	// Make path to settings file
279*9949213aSStephan Aßmus 	BPath path;
280*9949213aSStephan Aßmus 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) {
281*9949213aSStephan Aßmus 		path.SetTo(SETTINGS_PATH);
282*9949213aSStephan Aßmus 		path.Append(SETTINGS_FILE);
283*9949213aSStephan Aßmus 	} else
284*9949213aSStephan Aßmus 		path.Append(SETTINGS_FILE);
285*9949213aSStephan Aßmus 
286*9949213aSStephan Aßmus 	// Open settings file (create it if there's no file) and write settings
287*9949213aSStephan Aßmus 	FILE *file = NULL;
288*9949213aSStephan Aßmus 	if ((file = fopen( path.Path(), "wb+"))) {
289*9949213aSStephan Aßmus 		fwrite(Settings, sizeof(SETTINGS), 1, file);
290*9949213aSStephan Aßmus 		fclose(file);
291*9949213aSStephan Aßmus 	}
292*9949213aSStephan Aßmus }
293*9949213aSStephan Aßmus 
294*9949213aSStephan Aßmus //---------------------------------------------------
295*9949213aSStephan Aßmus //	Return true if Settings were run, false if not
296*9949213aSStephan Aßmus //---------------------------------------------------
297*9949213aSStephan Aßmus inline bool
298*9949213aSStephan Aßmus SettingsChangedAlert()
299*9949213aSStephan Aßmus {
300*9949213aSStephan Aßmus 	// If settings view wasn't already initialized (settings not running)
301*9949213aSStephan Aßmus 	// and user wants to run settings
302*9949213aSStephan Aßmus 	if (!AreSettingsRunning && (new BAlert("Different settings file", "JPEG settings were set to default because of incompatible settings file.", "Configure settings", "OK", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go() == 0) {
303*9949213aSStephan Aßmus 		// Create settings window (with no quit on close!), launch it and wait until it's closed
304*9949213aSStephan Aßmus 		status_t err;
305*9949213aSStephan Aßmus 		TranslatorWindow *window = new TranslatorWindow(false);
306*9949213aSStephan Aßmus 		window->Show();
307*9949213aSStephan Aßmus 		wait_for_thread(window->Thread(), &err);
308*9949213aSStephan Aßmus 		return true;
309*9949213aSStephan Aßmus 	}
310*9949213aSStephan Aßmus 
311*9949213aSStephan Aßmus 	return false;
312*9949213aSStephan Aßmus }
313*9949213aSStephan Aßmus 
314*9949213aSStephan Aßmus //---------------------------------------------------
315*9949213aSStephan Aßmus //	Load settings from config file
316*9949213aSStephan Aßmus //	If can't find it make them default and try to save
317*9949213aSStephan Aßmus //---------------------------------------------------
318*9949213aSStephan Aßmus inline void
319*9949213aSStephan Aßmus LoadSettings(SETTINGS *Settings)
320*9949213aSStephan Aßmus {
321*9949213aSStephan Aßmus 	// Make path to settings file
322*9949213aSStephan Aßmus 	BPath path;
323*9949213aSStephan Aßmus 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) {
324*9949213aSStephan Aßmus 		path.SetTo(SETTINGS_PATH);
325*9949213aSStephan Aßmus 		path.Append(SETTINGS_FILE);
326*9949213aSStephan Aßmus 	} else
327*9949213aSStephan Aßmus 		path.Append(SETTINGS_FILE);
328*9949213aSStephan Aßmus 
329*9949213aSStephan Aßmus 	// Open settings file (create it if there's no file) and write settings
330*9949213aSStephan Aßmus 	FILE *file = NULL;
331*9949213aSStephan Aßmus 	if ((file = fopen( path.Path(), "rb"))) {
332*9949213aSStephan Aßmus 		if ( !fread(Settings, sizeof(SETTINGS), 1, file)) {
333*9949213aSStephan Aßmus 			// Settings struct has changed size
334*9949213aSStephan Aßmus 			// Load default settings, and Save them
335*9949213aSStephan Aßmus 			fclose(file);
336*9949213aSStephan Aßmus 			LoadDefaultSettings(Settings);
337*9949213aSStephan Aßmus 			SaveSettings(Settings);
338*9949213aSStephan Aßmus 			// Tell user settings were changed to default, and ask to run settings panel or not
339*9949213aSStephan Aßmus 			if (SettingsChangedAlert())
340*9949213aSStephan Aßmus 				// User configured settings, load them again
341*9949213aSStephan Aßmus 				LoadSettings(Settings);
342*9949213aSStephan Aßmus 		} else
343*9949213aSStephan Aßmus 			fclose(file);
344*9949213aSStephan Aßmus 	} else if ((file = fopen( path.Path(), "wb+"))) {
345*9949213aSStephan Aßmus 		LoadDefaultSettings(Settings);
346*9949213aSStephan Aßmus 		fwrite(Settings, sizeof(SETTINGS), 1, file);
347*9949213aSStephan Aßmus 		fclose(file);
348*9949213aSStephan Aßmus 		// Tell user settings were changed to default, and ask to run settings panel or not
349*9949213aSStephan Aßmus 		if (SettingsChangedAlert())
350*9949213aSStephan Aßmus 			// User configured settings, load them again
351*9949213aSStephan Aßmus 			LoadSettings(Settings);
352*9949213aSStephan Aßmus 	}
353*9949213aSStephan Aßmus }
354*9949213aSStephan Aßmus 
355*9949213aSStephan Aßmus 
356*9949213aSStephan Aßmus //----------------------------------------------------------------------------
357*9949213aSStephan Aßmus //
358*9949213aSStephan Aßmus //	Functions
359*9949213aSStephan Aßmus //
360*9949213aSStephan Aßmus //----------------------------------------------------------------------------
361*9949213aSStephan Aßmus 
362*9949213aSStephan Aßmus //---------------------------------------------------
363*9949213aSStephan Aßmus //	"Initializers" for jpeglib
364*9949213aSStephan Aßmus //	based on default ones,
365*9949213aSStephan Aßmus //	modified to work on BPositionIO instead of FILE
366*9949213aSStephan Aßmus //---------------------------------------------------
367*9949213aSStephan Aßmus EXTERN(void) be_jpeg_stdio_src(j_decompress_ptr cinfo, BPositionIO *infile);	// from "be_jdatasrc.cpp"
368*9949213aSStephan Aßmus EXTERN(void) be_jpeg_stdio_dest(j_compress_ptr cinfo, BPositionIO *outfile);	// from "be_jdatadst.cpp"
369*9949213aSStephan Aßmus 
370*9949213aSStephan Aßmus //---------------------------------------------------
371*9949213aSStephan Aßmus //	Error output functions
372*9949213aSStephan Aßmus //	based on the one from jerror.c
373*9949213aSStephan Aßmus //	modified to use settings
374*9949213aSStephan Aßmus //	(so user can decide to show dialog-boxes or not)
375*9949213aSStephan Aßmus //---------------------------------------------------
376*9949213aSStephan Aßmus EXTERN(struct jpeg_error_mgr *) be_jpeg_std_error (struct jpeg_error_mgr * err, SETTINGS * settings); // from "be_jerror.cpp"
377*9949213aSStephan Aßmus 
378*9949213aSStephan Aßmus //---------------------------------------------------
379*9949213aSStephan Aßmus //	Main functions of translator :)
380*9949213aSStephan Aßmus //---------------------------------------------------
381*9949213aSStephan Aßmus status_t Copy(BPositionIO *in, BPositionIO *out);
382*9949213aSStephan Aßmus status_t Compress(BPositionIO *in, BPositionIO *out);
383*9949213aSStephan Aßmus status_t Decompress(BPositionIO *in, BPositionIO *out);
384*9949213aSStephan Aßmus status_t Error(j_common_ptr cinfo, status_t error = B_ERROR);
385*9949213aSStephan Aßmus 
386*9949213aSStephan Aßmus //---------------------------------------------------
387*9949213aSStephan Aßmus //	GRAY1 to GRAY8
388*9949213aSStephan Aßmus //---------------------------------------------------
389*9949213aSStephan Aßmus inline void
390*9949213aSStephan Aßmus convert_from_gray1_to_gray8(uchar *in, uchar *out, int in_bytes)
391*9949213aSStephan Aßmus {
392*9949213aSStephan Aßmus 	const color_map * map = system_colors();
393*9949213aSStephan Aßmus 	int32 index = 0;
394*9949213aSStephan Aßmus 	int32 index2 = 0;
395*9949213aSStephan Aßmus 	while (index < in_bytes) {
396*9949213aSStephan Aßmus 		unsigned char c = in[index++];
397*9949213aSStephan Aßmus 		for (int b = 128; b; b = b>>1) {
398*9949213aSStephan Aßmus 			unsigned char color;
399*9949213aSStephan Aßmus 			if (c & b)
400*9949213aSStephan Aßmus 				color = 0;
401*9949213aSStephan Aßmus 			else
402*9949213aSStephan Aßmus 				color = 255;
403*9949213aSStephan Aßmus 			out[index2++] = color;
404*9949213aSStephan Aßmus 		}
405*9949213aSStephan Aßmus 	}
406*9949213aSStephan Aßmus }
407*9949213aSStephan Aßmus 
408*9949213aSStephan Aßmus //---------------------------------------------------
409*9949213aSStephan Aßmus //	GRAY1 to RGB 8:8:8
410*9949213aSStephan Aßmus //---------------------------------------------------
411*9949213aSStephan Aßmus inline void
412*9949213aSStephan Aßmus convert_from_gray1_to_24(uchar *in, uchar *out, int in_bytes)
413*9949213aSStephan Aßmus {
414*9949213aSStephan Aßmus 	const color_map * map = system_colors();
415*9949213aSStephan Aßmus 	int32 index = 0;
416*9949213aSStephan Aßmus 	int32 index2 = 0;
417*9949213aSStephan Aßmus 	while (index < in_bytes) {
418*9949213aSStephan Aßmus 		unsigned char c = in[index++];
419*9949213aSStephan Aßmus 		for (int b = 128; b; b = b>>1) {
420*9949213aSStephan Aßmus 			unsigned char color;
421*9949213aSStephan Aßmus 			if (c & b)
422*9949213aSStephan Aßmus 				color = 0;
423*9949213aSStephan Aßmus 			else
424*9949213aSStephan Aßmus 				color = 255;
425*9949213aSStephan Aßmus 			out[index2++] = color;
426*9949213aSStephan Aßmus 			out[index2++] = color;
427*9949213aSStephan Aßmus 			out[index2++] = color;
428*9949213aSStephan Aßmus 		}
429*9949213aSStephan Aßmus 	}
430*9949213aSStephan Aßmus }
431*9949213aSStephan Aßmus 
432*9949213aSStephan Aßmus //---------------------------------------------------
433*9949213aSStephan Aßmus //	CMAP8 to RGB 8:8:8
434*9949213aSStephan Aßmus //---------------------------------------------------
435*9949213aSStephan Aßmus inline void
436*9949213aSStephan Aßmus convert_from_cmap8_to_24(uchar *in, uchar *out, int in_bytes)
437*9949213aSStephan Aßmus {
438*9949213aSStephan Aßmus 	const color_map * map = system_colors();
439*9949213aSStephan Aßmus 	int32 index = 0;
440*9949213aSStephan Aßmus 	int32 index2 = 0;
441*9949213aSStephan Aßmus 	while (index < in_bytes) {
442*9949213aSStephan Aßmus 		rgb_color color = map->color_list[in[index++]];
443*9949213aSStephan Aßmus 
444*9949213aSStephan Aßmus 		out[index2++] = color.red;
445*9949213aSStephan Aßmus 		out[index2++] = color.green;
446*9949213aSStephan Aßmus 		out[index2++] = color.blue;
447*9949213aSStephan Aßmus 	}
448*9949213aSStephan Aßmus }
449*9949213aSStephan Aßmus 
450*9949213aSStephan Aßmus //---------------------------------------------------
451*9949213aSStephan Aßmus //	BGR 1:5:5:5 to RGB 8:8:8
452*9949213aSStephan Aßmus //---------------------------------------------------
453*9949213aSStephan Aßmus inline void
454*9949213aSStephan Aßmus convert_from_15_to_24(uchar *in, uchar *out, int in_bytes)
455*9949213aSStephan Aßmus {
456*9949213aSStephan Aßmus 	int32 index = 0;
457*9949213aSStephan Aßmus 	int32 index2 = 0;
458*9949213aSStephan Aßmus 	int16 in_pixel;
459*9949213aSStephan Aßmus 	while (index < in_bytes) {
460*9949213aSStephan Aßmus 		in_pixel = in[index] | (in[index+1] << 8);
461*9949213aSStephan Aßmus 		index += 2;
462*9949213aSStephan Aßmus 
463*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x7c00)) >> 7) | (((in_pixel & 0x7c00)) >> 12);
464*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x3e0)) >> 2) | (((in_pixel & 0x3e0)) >> 7);
465*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2);
466*9949213aSStephan Aßmus 	}
467*9949213aSStephan Aßmus }
468*9949213aSStephan Aßmus 
469*9949213aSStephan Aßmus //---------------------------------------------------
470*9949213aSStephan Aßmus //	RGB 1:5:5:5 to RGB 8:8:8
471*9949213aSStephan Aßmus //---------------------------------------------------
472*9949213aSStephan Aßmus inline void
473*9949213aSStephan Aßmus convert_from_15b_to_24(uchar *in, uchar *out, int in_bytes)
474*9949213aSStephan Aßmus {
475*9949213aSStephan Aßmus 	int32 index = 0;
476*9949213aSStephan Aßmus 	int32 index2 = 0;
477*9949213aSStephan Aßmus 	int16 in_pixel;
478*9949213aSStephan Aßmus 	while (index < in_bytes) {
479*9949213aSStephan Aßmus 		in_pixel = in[index+1] | (in[index] << 8);
480*9949213aSStephan Aßmus 		index += 2;
481*9949213aSStephan Aßmus 
482*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x7c00)) >> 7) | (((in_pixel & 0x7c00)) >> 12);
483*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x3e0)) >> 2) | (((in_pixel & 0x3e0)) >> 7);
484*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2);
485*9949213aSStephan Aßmus 	}
486*9949213aSStephan Aßmus }
487*9949213aSStephan Aßmus 
488*9949213aSStephan Aßmus //---------------------------------------------------
489*9949213aSStephan Aßmus //	BGR 5:6:5 to RGB 8:8:8
490*9949213aSStephan Aßmus //---------------------------------------------------
491*9949213aSStephan Aßmus inline void
492*9949213aSStephan Aßmus convert_from_16_to_24(uchar *in, uchar *out, int in_bytes)
493*9949213aSStephan Aßmus {
494*9949213aSStephan Aßmus 	int32 index = 0;
495*9949213aSStephan Aßmus 	int32 index2 = 0;
496*9949213aSStephan Aßmus 	int16 in_pixel;
497*9949213aSStephan Aßmus 	while (index < in_bytes) {
498*9949213aSStephan Aßmus 		in_pixel = in[index] | (in[index+1] << 8);
499*9949213aSStephan Aßmus 		index += 2;
500*9949213aSStephan Aßmus 
501*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0xf800)) >> 8) | (((in_pixel & 0xf800)) >> 13);
502*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x7e0)) >> 3) | (((in_pixel & 0x7e0)) >> 9);
503*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2);
504*9949213aSStephan Aßmus 	}
505*9949213aSStephan Aßmus }
506*9949213aSStephan Aßmus 
507*9949213aSStephan Aßmus //---------------------------------------------------
508*9949213aSStephan Aßmus //	RGB 5:6:5 to RGB 8:8:8
509*9949213aSStephan Aßmus //---------------------------------------------------
510*9949213aSStephan Aßmus inline void
511*9949213aSStephan Aßmus convert_from_16b_to_24(uchar *in, uchar *out, int in_bytes)
512*9949213aSStephan Aßmus {
513*9949213aSStephan Aßmus 	int32 index = 0;
514*9949213aSStephan Aßmus 	int32 index2 = 0;
515*9949213aSStephan Aßmus 	int16 in_pixel;
516*9949213aSStephan Aßmus 	while (index < in_bytes) {
517*9949213aSStephan Aßmus 		in_pixel = in[index+1] | (in[index] << 8);
518*9949213aSStephan Aßmus 		index += 2;
519*9949213aSStephan Aßmus 
520*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0xf800)) >> 8) | (((in_pixel & 0xf800)) >> 13);
521*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x7e0)) >> 3) | (((in_pixel & 0x7e0)) >> 9);
522*9949213aSStephan Aßmus 		out[index2++] = (((in_pixel & 0x1f)) << 3) | (((in_pixel & 0x1f)) >> 2);
523*9949213aSStephan Aßmus 	}
524*9949213aSStephan Aßmus }
525*9949213aSStephan Aßmus 
526*9949213aSStephan Aßmus //---------------------------------------------------
527*9949213aSStephan Aßmus //	BGR 8:8:8 to RGB 8:8:8
528*9949213aSStephan Aßmus //---------------------------------------------------
529*9949213aSStephan Aßmus inline void
530*9949213aSStephan Aßmus convert_from_24_to_24(uchar *in, uchar *out, int in_bytes)
531*9949213aSStephan Aßmus {
532*9949213aSStephan Aßmus 	int32 index = 0;
533*9949213aSStephan Aßmus 	int32 index2 = 0;
534*9949213aSStephan Aßmus 	while (index < in_bytes) {
535*9949213aSStephan Aßmus 		out[index2++] = in[index+2];
536*9949213aSStephan Aßmus 		out[index2++] = in[index+1];
537*9949213aSStephan Aßmus 		out[index2++] = in[index];
538*9949213aSStephan Aßmus 		index+=3;
539*9949213aSStephan Aßmus 	}
540*9949213aSStephan Aßmus }
541*9949213aSStephan Aßmus 
542*9949213aSStephan Aßmus //---------------------------------------------------
543*9949213aSStephan Aßmus //	BGRx 8:8:8:8 to RGB 8:8:8
544*9949213aSStephan Aßmus //---------------------------------------------------
545*9949213aSStephan Aßmus inline void
546*9949213aSStephan Aßmus convert_from_32_to_24(uchar *in, uchar *out, int in_bytes)
547*9949213aSStephan Aßmus {
548*9949213aSStephan Aßmus 	int32 index = 0;
549*9949213aSStephan Aßmus 	int32 index2 = 0;
550*9949213aSStephan Aßmus 	while (index < in_bytes) {
551*9949213aSStephan Aßmus 		out[index2++] = in[index+2];
552*9949213aSStephan Aßmus 		out[index2++] = in[index+1];
553*9949213aSStephan Aßmus 		out[index2++] = in[index];
554*9949213aSStephan Aßmus 		index+=4;
555*9949213aSStephan Aßmus 	}
556*9949213aSStephan Aßmus }
557*9949213aSStephan Aßmus 
558*9949213aSStephan Aßmus //---------------------------------------------------
559*9949213aSStephan Aßmus //	xRGB 8:8:8:8 to RGB 8:8:8
560*9949213aSStephan Aßmus //---------------------------------------------------
561*9949213aSStephan Aßmus inline void
562*9949213aSStephan Aßmus convert_from_32b_to_24(uchar *in, uchar *out, int in_bytes)
563*9949213aSStephan Aßmus {
564*9949213aSStephan Aßmus 	int32 index = 0;
565*9949213aSStephan Aßmus 	int32 index2 = 0;
566*9949213aSStephan Aßmus 	while (index < in_bytes) {
567*9949213aSStephan Aßmus 		index++;
568*9949213aSStephan Aßmus 		out[index2++] = in[index++];
569*9949213aSStephan Aßmus 		out[index2++] = in[index++];
570*9949213aSStephan Aßmus 		out[index2++] = in[index++];
571*9949213aSStephan Aßmus 	}
572*9949213aSStephan Aßmus }
573*9949213aSStephan Aßmus 
574*9949213aSStephan Aßmus //---------------------------------------------------
575*9949213aSStephan Aßmus //	CMYK 8:8:8:8 to RGB32 8:8:8:8
576*9949213aSStephan Aßmus //	Version for Adobe Photoshop files (0 for 100% ink)
577*9949213aSStephan Aßmus //---------------------------------------------------
578*9949213aSStephan Aßmus inline void
579*9949213aSStephan Aßmus convert_from_CMYK_to_32_photoshop (uchar *in, uchar *out, int out_bytes)
580*9949213aSStephan Aßmus {
581*9949213aSStephan Aßmus 	int32 index = 0;
582*9949213aSStephan Aßmus 	int32 index2 = 0;
583*9949213aSStephan Aßmus 	int32 black = 0;
584*9949213aSStephan Aßmus 	while (index < out_bytes) {
585*9949213aSStephan Aßmus 		black = in[index2+3];
586*9949213aSStephan Aßmus 		out[index++] = in[index2+2]*black/255;
587*9949213aSStephan Aßmus 		out[index++] = in[index2+1]*black/255;
588*9949213aSStephan Aßmus 		out[index++] = in[index2]*black/255;
589*9949213aSStephan Aßmus 		out[index++] = 255;
590*9949213aSStephan Aßmus 		index2 += 4;
591*9949213aSStephan Aßmus 	}
592*9949213aSStephan Aßmus }
593*9949213aSStephan Aßmus 
594*9949213aSStephan Aßmus //---------------------------------------------------
595*9949213aSStephan Aßmus //	CMYK 8:8:8:8 to RGB32 8:8:8:8
596*9949213aSStephan Aßmus //	!!! UNTESTED !!!
597*9949213aSStephan Aßmus //---------------------------------------------------
598*9949213aSStephan Aßmus inline void
599*9949213aSStephan Aßmus convert_from_CMYK_to_32 (uchar *in, uchar *out, int out_bytes)
600*9949213aSStephan Aßmus {
601*9949213aSStephan Aßmus 	int32 index = 0;
602*9949213aSStephan Aßmus 	int32 index2 = 0;
603*9949213aSStephan Aßmus 	int32 black = 0;
604*9949213aSStephan Aßmus 	while (index < out_bytes) {
605*9949213aSStephan Aßmus 		black = 255 - in[index2+3];
606*9949213aSStephan Aßmus 		out[index++] = ((255-in[index2+2])*black)/255;
607*9949213aSStephan Aßmus 		out[index++] = ((255-in[index2+1])*black)/255;
608*9949213aSStephan Aßmus 		out[index++] = ((255-in[index2])*black)/255;
609*9949213aSStephan Aßmus 		out[index++] = 255;
610*9949213aSStephan Aßmus 		index2 += 4;
611*9949213aSStephan Aßmus 	}
612*9949213aSStephan Aßmus }
613*9949213aSStephan Aßmus 
614*9949213aSStephan Aßmus //---------------------------------------------------
615*9949213aSStephan Aßmus //	RGB24 8:8:8 to xRGB 8:8:8:8
616*9949213aSStephan Aßmus //---------------------------------------------------
617*9949213aSStephan Aßmus inline void
618*9949213aSStephan Aßmus convert_from_24_to_32(uchar *in, uchar *out, int out_bytes)
619*9949213aSStephan Aßmus {
620*9949213aSStephan Aßmus 	int32 index = 0;
621*9949213aSStephan Aßmus 	int32 index2 = 0;
622*9949213aSStephan Aßmus 	while (index < out_bytes) {
623*9949213aSStephan Aßmus 		out[index++] = in[index2+2];
624*9949213aSStephan Aßmus 		out[index++] = in[index2+1];
625*9949213aSStephan Aßmus 		out[index++] = in[index2];
626*9949213aSStephan Aßmus 		out[index++] = 255;
627*9949213aSStephan Aßmus 		index2 += 3;
628*9949213aSStephan Aßmus 	}
629*9949213aSStephan Aßmus }
630*9949213aSStephan Aßmus 
631*9949213aSStephan Aßmus 
632*9949213aSStephan Aßmus #endif // _JPEGTRANSLATOR_H_
633