TCP: Fixed RTO update and dup ACKs generation.
[haiku.git] / src / add-ons / translators / gif / GIFTranslator.cpp
blob98b4b957a19035d5172087f9e38386ea7fd02c3a
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: GIFTranslator.cpp
4 //
5 // Date: December 1999
6 //
7 // Author: Daniel Switkin
8 //
9 // Copyright 2003 (c) by Daniel Switkin. This file is made publically available
10 // under the BSD license, with the stipulations that this complete header must
11 // remain at the top of the file indefinitely, and credit must be given to the
12 // original author in any about box using this software.
14 ////////////////////////////////////////////////////////////////////////////////
16 // Additional authors: Stephan Aßmus, <superstippi@gmx.de>
17 // John Scipione, <jscipione@gmail.com>
19 #include "GIFTranslator.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <syslog.h>
26 #include <Application.h>
27 #include <ByteOrder.h>
28 #include <Catalog.h>
29 #include <DataIO.h>
30 #include <InterfaceDefs.h>
31 #include <TranslatorAddOn.h>
32 #include <TranslatorFormats.h>
33 #include <TypeConstants.h>
35 #include "GIFLoad.h"
36 #include "GIFSave.h"
37 #include "GIFView.h"
38 #include "TranslatorWindow.h"
41 #ifndef GIF_TYPE
42 #define GIF_TYPE 'GIF '
43 #endif
45 #undef B_TRANSLATION_CONTEXT
46 #define B_TRANSLATION_CONTEXT "GIFTranslator"
49 bool debug = false;
50 // this global will be externed in other files - set once here
51 // for the entire translator
53 bool DetermineType(BPositionIO* source, bool* isGif);
54 status_t GetBitmap(BPositionIO* in, BBitmap** out);
56 static const translation_format sInputFormats[] = {
58 GIF_TYPE,
59 B_TRANSLATOR_BITMAP,
60 GIF_IN_QUALITY,
61 GIF_IN_CAPABILITY,
62 "image/gif",
63 "GIF image"
66 B_TRANSLATOR_BITMAP,
67 B_TRANSLATOR_BITMAP,
68 BBM_IN_QUALITY,
69 BBM_IN_CAPABILITY,
70 "image/x-be-bitmap",
71 "Be Bitmap Format (GIFTranslator)"
75 static const translation_format sOutputFormats[] = {
77 GIF_TYPE,
78 B_TRANSLATOR_BITMAP,
79 GIF_OUT_QUALITY,
80 GIF_OUT_CAPABILITY,
81 "image/gif",
82 "GIF image"
85 B_TRANSLATOR_BITMAP,
86 B_TRANSLATOR_BITMAP,
87 BBM_OUT_QUALITY,
88 BBM_OUT_CAPABILITY,
89 "image/x-be-bitmap",
90 "Be Bitmap Format (GIFTranslator)"
94 // Default settings for the Translator
95 static const TranSetting sDefaultSettings[] = {
96 { B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false },
97 { B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false },
98 { GIF_SETTING_INTERLACED, TRAN_SETTING_BOOL, false },
99 { GIF_SETTING_USE_TRANSPARENT, TRAN_SETTING_BOOL, true },
100 { GIF_SETTING_USE_TRANSPARENT_AUTO, TRAN_SETTING_BOOL, true },
101 { GIF_SETTING_USE_DITHERING, TRAN_SETTING_BOOL, false },
102 { GIF_SETTING_PALETTE_MODE, TRAN_SETTING_INT32, 3 },
103 { GIF_SETTING_PALETTE_SIZE, TRAN_SETTING_INT32, 8 },
104 { GIF_SETTING_TRANSPARENT_RED, TRAN_SETTING_INT32, 255 },
105 { GIF_SETTING_TRANSPARENT_GREEN, TRAN_SETTING_INT32, 255 },
106 { GIF_SETTING_TRANSPARENT_BLUE, TRAN_SETTING_INT32, 255 }
109 const uint32 kNumInputFormats = sizeof(sInputFormats)
110 / sizeof(translation_format);
111 const uint32 kNumOutputFormats = sizeof(sOutputFormats)
112 / sizeof(translation_format);
113 const uint32 kNumDefaultSettings = sizeof(sDefaultSettings)
114 / sizeof(TranSetting);
117 /*! Look at first few bytes in stream to determine type - throw it back
118 if it is not a GIF or a BBitmap that we understand.
120 bool
121 DetermineType(BPositionIO* source, bool* isGif)
123 unsigned char header[7];
124 *isGif = true;
125 if (source->Read(header, 6) != 6)
126 return false;
128 header[6] = 0x00;
130 if (strcmp((char*)header, "GIF87a") != 0
131 && strcmp((char*)header, "GIF89a") != 0) {
132 *isGif = false;
133 int32 magic = (header[0] << 24) + (header[1] << 16) + (header[2] << 8)
134 + header[3];
135 if (magic != B_TRANSLATOR_BITMAP)
136 return false;
138 source->Seek(5 * 4 - 2, SEEK_CUR);
139 color_space cs;
140 if (source->Read(&cs, 4) != 4)
141 return false;
143 cs = (color_space)B_BENDIAN_TO_HOST_INT32(cs);
144 if (cs != B_RGB32 && cs != B_RGBA32 && cs != B_RGB32_BIG
145 && cs != B_RGBA32_BIG) {
146 return false;
150 source->Seek(0, SEEK_SET);
151 return true;
155 status_t
156 GetBitmap(BPositionIO* in, BBitmap** out)
158 TranslatorBitmap header;
159 status_t result = in->Read(&header, sizeof(header));
160 if (result != sizeof(header))
161 return B_IO_ERROR;
163 header.magic = B_BENDIAN_TO_HOST_INT32(header.magic);
164 header.bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left);
165 header.bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top);
166 header.bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right);
167 header.bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
168 header.rowBytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
169 header.colors = (color_space)B_BENDIAN_TO_HOST_INT32(header.colors);
170 header.dataSize = B_BENDIAN_TO_HOST_INT32(header.dataSize);
172 // dump data from stream into a BBitmap
173 *out = new(std::nothrow) BBitmap(header.bounds, header.colors);
174 if (*out == NULL)
175 return B_NO_MEMORY;
177 if (!(*out)->IsValid()) {
178 delete *out;
179 return B_NO_MEMORY;
182 result = in->Read((*out)->Bits(), header.dataSize);
183 if (result != (status_t)header.dataSize) {
184 delete *out;
185 return B_IO_ERROR;
188 return B_OK;
192 /*! Required identify function - may need to read entire header, not sure
194 status_t
195 GIFTranslator::DerivedIdentify(BPositionIO* inSource,
196 const translation_format* inFormat, BMessage* ioExtension,
197 translator_info* outInfo, uint32 outType)
199 const char* debug_text = getenv("GIF_TRANSLATOR_DEBUG");
200 if (debug_text != NULL && atoi(debug_text) != 0)
201 debug = true;
203 if (outType == 0)
204 outType = B_TRANSLATOR_BITMAP;
206 if (outType != GIF_TYPE && outType != B_TRANSLATOR_BITMAP)
207 return B_NO_TRANSLATOR;
209 bool isGif;
210 if (!DetermineType(inSource, &isGif))
211 return B_NO_TRANSLATOR;
213 if (!isGif && inFormat != NULL && inFormat->type != B_TRANSLATOR_BITMAP)
214 return B_NO_TRANSLATOR;
216 outInfo->group = B_TRANSLATOR_BITMAP;
217 if (isGif) {
218 outInfo->type = GIF_TYPE;
219 outInfo->quality = GIF_IN_QUALITY;
220 outInfo->capability = GIF_IN_CAPABILITY;
221 strlcpy(outInfo->name, B_TRANSLATE("GIF image"), sizeof(outInfo->name));
222 strcpy(outInfo->MIME, "image/gif");
223 } else {
224 outInfo->type = B_TRANSLATOR_BITMAP;
225 outInfo->quality = BBM_IN_QUALITY;
226 outInfo->capability = BBM_IN_CAPABILITY;
227 strlcpy(outInfo->name, B_TRANSLATE("Be Bitmap Format (GIFTranslator)"),
228 sizeof(outInfo->name));
229 strcpy(outInfo->MIME, "image/x-be-bitmap");
232 return B_OK;
236 /*! Main required function - assumes that an incoming GIF must be translated
237 to a BBitmap, and vice versa - this could be improved
239 status_t
240 GIFTranslator::DerivedTranslate(BPositionIO* inSource,
241 const translator_info* inInfo, BMessage* ioExtension, uint32 outType,
242 BPositionIO* outDestination, int32 baseType)
244 const char* debug_text = getenv("GIF_TRANSLATOR_DEBUG");
245 if (debug_text != NULL && atoi(debug_text) != 0)
246 debug = true;
248 if (outType == 0)
249 outType = B_TRANSLATOR_BITMAP;
251 if (outType != GIF_TYPE && outType != B_TRANSLATOR_BITMAP)
252 return B_NO_TRANSLATOR;
254 bool isGif;
255 if (!DetermineType(inSource, &isGif))
256 return B_NO_TRANSLATOR;
258 if (!isGif && inInfo->type != B_TRANSLATOR_BITMAP)
259 return B_NO_TRANSLATOR;
261 status_t result = B_OK;
262 bigtime_t now = system_time();
264 if (!isGif) {
265 // BBitmap to GIF
266 BBitmap* bitmap;
267 result = GetBitmap(inSource, &bitmap);
268 if (result != B_OK)
269 return result;
271 GIFSave* gifSave = new(std::nothrow) GIFSave(bitmap, outDestination,
272 fSettings);
273 if (gifSave == NULL) {
274 delete bitmap;
275 return B_NO_MEMORY;
278 if (gifSave->fatalerror) {
279 delete gifSave;
280 delete bitmap;
281 return B_NO_MEMORY;
283 delete gifSave;
284 delete bitmap;
285 } else {
286 // GIF to BBitmap
287 GIFLoad* gifLoad = new(std::nothrow) GIFLoad(inSource, outDestination);
288 if (gifLoad == NULL)
289 return B_NO_MEMORY;
291 if (gifLoad->fatalerror) {
292 delete gifLoad;
293 return B_NO_MEMORY;
295 delete gifLoad;
298 if (debug) {
299 now = system_time() - now;
300 syslog(LOG_INFO, "Translate() - Translation took %Ld microseconds\n",
301 now);
303 return B_OK;
307 BTranslator*
308 make_nth_translator(int32 n, image_id you, uint32 flags, ...)
310 if (n == 0)
311 return new(std::nothrow) GIFTranslator();
313 return NULL;
317 GIFTranslator::GIFTranslator()
319 BaseTranslator(B_TRANSLATE("GIF images"),
320 B_TRANSLATE("GIF image translator"),
321 GIF_TRANSLATOR_VERSION,
322 sInputFormats, kNumInputFormats,
323 sOutputFormats, kNumOutputFormats,
324 "GIFTranslator_Settings",
325 sDefaultSettings, kNumDefaultSettings,
326 B_TRANSLATOR_BITMAP, B_GIF_FORMAT)
331 GIFTranslator::~GIFTranslator()
336 BView*
337 GIFTranslator::NewConfigView(TranslatorSettings* settings)
339 return new(std::nothrow) GIFView(settings);
344 main()
346 BApplication app("application/x-vnd.Haiku-GIFTranslator");
347 status_t result = LaunchTranslatorWindow(new(std::nothrow) GIFTranslator,
348 B_TRANSLATE("GIF Settings"), kRectView);
349 if (result == B_OK) {
350 app.Run();
351 return 0;
354 return 1;