xref: /haiku/src/add-ons/translators/sgi/SGITranslator.cpp (revision 125183f9e5c136781f71c879faaeab43fdc3ea7b)
1 /*****************************************************************************/
2 // SGITranslator
3 // Written by Stephan Aßmus
4 // based on TIFFTranslator written mostly by
5 // Michael Wilber
6 //
7 // SGITranslator.cpp
8 //
9 // This BTranslator based object is for opening and writing
10 // SGI images.
11 //
12 //
13 // Copyright (c) 2003-2009 Haiku, Inc. All rights reserved.
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a
16 // copy of this software and associated documentation files (the "Software"),
17 // to deal in the Software without restriction, including without limitation
18 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
19 // and/or sell copies of the Software, and to permit persons to whom the
20 // Software is furnished to do so, subject to the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be included
23 // in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 // DEALINGS IN THE SOFTWARE.
32 /*****************************************************************************/
33 //
34 // How this works:
35 //
36 // libtiff has a special version of SGIOpen() that gets passed custom
37 // functions for reading writing etc. and a handle. This handle in our case
38 // is a BPositionIO object, which libtiff passes on to the functions for reading
39 // writing etc. So when operations are performed on the SGI* handle that is
40 // returned by SGIOpen(), libtiff uses the special reading writing etc
41 // functions so that all stream io happens on the BPositionIO object.
42 
43 #include <new>
44 #include <stdio.h>
45 #include <string.h>
46 
47 #include <OS.h>
48 
49 #include "SGIImage.h"
50 #include "SGITranslator.h"
51 #include "SGIView.h"
52 
53 using std::nothrow;
54 
55 // The input formats that this translator supports.
56 translation_format gInputFormats[] = {
57 	{
58 		B_TRANSLATOR_BITMAP,
59 		B_TRANSLATOR_BITMAP,
60 		BBT_IN_QUALITY,
61 		BBT_IN_CAPABILITY,
62 		"image/x-be-bitmap",
63 		"Be Bitmap Format (SGITranslator)"
64 	},
65 	{
66 		SGI_FORMAT,
67 		B_TRANSLATOR_BITMAP,
68 		SGI_IN_QUALITY,
69 		SGI_IN_CAPABILITY,
70 		"image/sgi",
71 		"SGI image"
72 	}
73 };
74 
75 // The output formats that this translator supports.
76 translation_format gOutputFormats[] = {
77 	{
78 		B_TRANSLATOR_BITMAP,
79 		B_TRANSLATOR_BITMAP,
80 		BBT_OUT_QUALITY,
81 		BBT_OUT_CAPABILITY,
82 		"image/x-be-bitmap",
83 		"Be Bitmap Format (SGITranslator)"
84 	},
85 	{
86 		SGI_FORMAT,
87 		B_TRANSLATOR_BITMAP,
88 		SGI_OUT_QUALITY,
89 		SGI_OUT_CAPABILITY,
90 		"image/sgi",
91 		"SGI image"
92 	}
93 };
94 
95 // Default settings for the Translator
96 TranSetting gDefaultSettings[] = {
97 	{B_TRANSLATOR_EXT_HEADER_ONLY, TRAN_SETTING_BOOL, false},
98 	{B_TRANSLATOR_EXT_DATA_ONLY, TRAN_SETTING_BOOL, false},
99 	{SGI_SETTING_COMPRESSION, TRAN_SETTING_INT32, SGI_COMP_RLE}
100 		// compression is set to RLE by default
101 };
102 
103 // ---------------------------------------------------------------
104 // make_nth_translator
105 //
106 // Creates a SGITranslator object to be used by BTranslatorRoster
107 //
108 // Preconditions:
109 //
110 // Parameters: n,		The translator to return. Since
111 //						SGITranslator only publishes one
112 //						translator, it only returns a
113 //						SGITranslator if n == 0
114 //
115 //             you, 	The image_id of the add-on that
116 //						contains code (not used).
117 //
118 //             flags,	Has no meaning yet, should be 0.
119 //
120 // Postconditions:
121 //
122 // Returns: NULL if n is not zero,
123 //          a new SGITranslator if n is zero
124 // ---------------------------------------------------------------
125 BTranslator *
126 make_nth_translator(int32 n, image_id you, uint32 flags, ...)
127 {
128 	if (!n)
129 		return new SGITranslator();
130 	else
131 		return NULL;
132 }
133 
134 // ---------------------------------------------------------------
135 // Constructor
136 //
137 // Sets up the version info and the name of the translator so that
138 // these values can be returned when they are requested.
139 //
140 // Preconditions:
141 //
142 // Parameters:
143 //
144 // Postconditions:
145 //
146 // Returns:
147 // ---------------------------------------------------------------
148 SGITranslator::SGITranslator()
149 	:
150 	BaseTranslator("SGI images", "SGI image translator",
151 		SGI_TRANSLATOR_VERSION,
152 		gInputFormats, sizeof(gInputFormats) / sizeof(translation_format),
153 		gOutputFormats, sizeof(gOutputFormats) / sizeof(translation_format),
154 		"SGITranslator_Settings",
155 		gDefaultSettings, sizeof(gDefaultSettings) / sizeof(TranSetting),
156 		B_TRANSLATOR_BITMAP, SGI_FORMAT)
157 {
158 }
159 
160 // ---------------------------------------------------------------
161 // Destructor
162 //
163 // Does nothing
164 //
165 // Preconditions:
166 //
167 // Parameters:
168 //
169 // Postconditions:
170 //
171 // Returns:
172 // ---------------------------------------------------------------
173 SGITranslator::~SGITranslator()
174 {
175 }
176 
177 status_t
178 identify_sgi_header(BPositionIO *inSource, translator_info *outInfo, uint32 outType,
179 	SGIImage **poutSGIImage = NULL)
180 {
181 	status_t status = B_NO_MEMORY;
182 	// construct new SGIImage object and set it to the provided BPositionIO
183 	SGIImage* sgiImage = new(nothrow) SGIImage();
184 	if (sgiImage)
185 		status = sgiImage->SetTo(inSource);
186 
187 	if (status >= B_OK) {
188 		if (outInfo) {
189 			outInfo->type = SGI_FORMAT;
190 			outInfo->group = B_TRANSLATOR_BITMAP;
191 			outInfo->quality = SGI_IN_QUALITY;
192 			outInfo->capability = SGI_IN_CAPABILITY;
193 			strcpy(outInfo->MIME, "image/sgi");
194 			strcpy(outInfo->name, "SGI image");
195 		}
196 	} else {
197 		delete sgiImage;
198 		sgiImage = NULL;
199 	}
200 	if (!poutSGIImage)
201 		// close SGIImage if caller is not interested in SGIImage handle
202 		delete sgiImage;
203 	else
204 		// leave SGIImage open (if it is) and return handle if caller needs it
205 		*poutSGIImage = sgiImage;
206 
207 	return status;
208 }
209 
210 // ---------------------------------------------------------------
211 // DerivedIdentify
212 //
213 // Examines the data from inSource and determines if it is in a
214 // format that this translator knows how to work with.
215 //
216 // Preconditions:
217 //
218 // Parameters:	inSource,	where the data to examine is
219 //
220 //				inFormat,	a hint about the data in inSource,
221 //							it is ignored since it is only a hint
222 //
223 //				ioExtension,	configuration settings for the
224 //								translator (not used)
225 //
226 //				outInfo,	information about what data is in
227 //							inSource and how well this translator
228 //							can handle that data is stored here
229 //
230 //				outType,	The format that the user wants
231 //							the data in inSource to be
232 //							converted to
233 //
234 // Postconditions:
235 //
236 // Returns: B_NO_TRANSLATOR,	if this translator can't handle
237 //								the data in inSource
238 //
239 // B_ERROR,	if there was an error converting the data to the host
240 //			format
241 //
242 // B_BAD_VALUE, if the settings in ioExtension are bad
243 //
244 // B_OK,	if this translator understood the data and there were
245 //			no errors found
246 //
247 // Other errors if BPositionIO::Read() returned an error value
248 // ---------------------------------------------------------------
249 status_t
250 SGITranslator::DerivedIdentify(BPositionIO *inSource,
251 	const translation_format *inFormat, BMessage *ioExtension,
252 	translator_info *outInfo, uint32 outType)
253 {
254 	return identify_sgi_header(inSource, outInfo, outType);
255 }
256 
257 // translate_from_bits
258 status_t
259 SGITranslator::translate_from_bits(BPositionIO *inSource, uint32 outType,
260 	BPositionIO *outDestination)
261 {
262 	TranslatorBitmap bitsHeader;
263 
264 	uint32 compression = fSettings->SetGetInt32(SGI_SETTING_COMPRESSION);
265 
266 	status_t ret = identify_bits_header(inSource, NULL, &bitsHeader);
267 	if (ret < B_OK)
268 		return ret;
269 
270 	// Translate B_TRANSLATOR_BITMAP to SGI_FORMAT
271 	if (outType == SGI_FORMAT) {
272 
273 		// common fields which are independent of the bitmap format
274 		uint32 width = bitsHeader.bounds.IntegerWidth() + 1;
275 		uint32 height = bitsHeader.bounds.IntegerHeight() + 1;
276 		uint32 bytesPerRow = bitsHeader.rowBytes;
277 		uint32 bytesPerChannel = 1;
278 		color_space format = bitsHeader.colors;
279 
280 		uint32 channelCount;
281 		switch (format) {
282 			case B_GRAY8:
283 				channelCount = 1;
284 				break;
285 			case B_RGB32:
286 			case B_RGB32_BIG:
287 			case B_RGB24:
288 			case B_RGB24_BIG:
289 				channelCount = 3;
290 				break;
291 			case B_RGBA32:
292 			case B_RGBA32_BIG:
293 				channelCount = 4;
294 				break;
295 			default:
296 				return B_NO_TRANSLATOR;
297 		}
298 
299 		// Set up SGI header
300 		SGIImage* sgiImage = new SGIImage();
301 		status_t ret = sgiImage->SetTo(outDestination, width, height,
302 									   channelCount, bytesPerChannel, compression);
303 		if (ret >= B_OK) {
304 			// read one row at a time,
305 			// convert to the correct format
306 			// and write out the results
307 
308 			// SGI Images store each channel separately
309 			// a buffer is allocated big enough to hold all channels
310 			// then the pointers are assigned with offsets into that buffer
311 			uint8** rows = new(nothrow) uint8*[channelCount];
312 			if (rows)
313 				rows[0] = new(nothrow) uint8[width * channelCount * bytesPerChannel];
314 			// rowBuffer is going to hold the converted data
315 			uint8* rowBuffer = new(nothrow) uint8[bytesPerRow];
316 			if (rows && rows[0] && rowBuffer) {
317 				// assign the other pointers (channel offsets in row buffer)
318 				for (uint32 i = 1; i < channelCount; i++)
319 					rows[i] = rows[0] + i * width;
320 				// loop through all lines of the image
321 				for (int32 y = height - 1; y >= 0 && ret >= B_OK; y--) {
322 
323 					ret = inSource->Read(rowBuffer, bytesPerRow);
324 					// see if an error happened while reading
325 					if (ret < B_OK)
326 						break;
327 					// convert to native format (big endian)
328 					switch (format) {
329 						case B_GRAY8: {
330 							uint8* src = rowBuffer;
331 							for (uint32 x = 0; x < width; x++) {
332 								rows[0][x] = src[0];
333 								src += 1;
334 							}
335 							break;
336 						}
337 						case B_RGB24: {
338 							uint8* src = rowBuffer;
339 							for (uint32 x = 0; x < width; x++) {
340 								rows[0][x] = src[2];
341 								rows[1][x] = src[1];
342 								rows[2][x] = src[0];
343 								src += 3;
344 							}
345 							break;
346 						}
347 						case B_RGB24_BIG: {
348 							uint8* src = rowBuffer;
349 							for (uint32 x = 0; x < width; x++) {
350 								rows[0][x] = src[0];
351 								rows[1][x] = src[1];
352 								rows[2][x] = src[2];
353 								src += 3;
354 							}
355 							break;
356 						}
357 						case B_RGB32: {
358 							uint8* src = rowBuffer;
359 							for (uint32 x = 0; x < width; x++) {
360 								rows[0][x] = src[2];
361 								rows[1][x] = src[1];
362 								rows[2][x] = src[0];
363 								// ignore src[3]
364 								src += 4;
365 							}
366 							break;
367 						}
368 						case B_RGB32_BIG: {
369 							uint8* src = rowBuffer;
370 							for (uint32 x = 0; x < width; x++) {
371 								rows[0][x] = src[1];
372 								rows[1][x] = src[2];
373 								rows[2][x] = src[3];
374 								// ignore src[0]
375 								src += 4;
376 							}
377 							break;
378 						}
379 						case B_RGBA32: {
380 							uint8* src = rowBuffer;
381 							for (uint32 x = 0; x < width; x++) {
382 								rows[0][x] = src[2];
383 								rows[1][x] = src[1];
384 								rows[2][x] = src[0];
385 								rows[3][x] = src[3];
386 								src += 4;
387 							}
388 							break;
389 						}
390 						case B_RGBA32_BIG: {
391 							uint8* src = rowBuffer;
392 							for (uint32 x = 0; x < width; x++) {
393 								rows[0][x] = src[1];
394 								rows[1][x] = src[2];
395 								rows[2][x] = src[3];
396 								rows[3][x] = src[0];
397 								src += 4;
398 							}
399 							break;
400 						}
401 						default:
402 							// cannot be here
403 							break;
404 					} // switch (format)
405 
406 					// for each channel, write a row buffer
407 					for (uint32 z = 0; z < channelCount; z++) {
408 						ret = sgiImage->WriteRow(rows[z], y, z);
409 						if (ret < B_OK) {
410 printf("WriteRow() returned %s!\n", strerror(ret));
411 							break;
412 						}
413 					}
414 
415 				} // for (uint32 y = 0; y < height && ret >= B_OK; y++)
416 				if (ret >= B_OK)
417 					ret = B_OK;
418 			} else // if (rows && rows[0] && rowBuffer)
419 				ret = B_NO_MEMORY;
420 
421 			delete[] rows[0];
422 			delete[] rows;
423 			delete[] rowBuffer;
424 		}
425 
426 		// done with the SGIImage object
427 		delete sgiImage;
428 
429 		return ret;
430 	}
431 	return B_NO_TRANSLATOR;
432 }
433 
434 // translate_from_sgi
435 status_t
436 SGITranslator::translate_from_sgi(BPositionIO *inSource, uint32 outType,
437 	BPositionIO *outDestination)
438 {
439 	status_t ret = B_NO_TRANSLATOR;
440 
441 	// if copying SGI_FORMAT to SGI_FORMAT
442 	if (outType == SGI_FORMAT) {
443 		translate_direct_copy(inSource, outDestination);
444 		return B_OK;
445 	}
446 
447 	// variables needing cleanup
448 	SGIImage* sgiImage = NULL;
449 
450 	ret = identify_sgi_header(inSource, NULL, outType, &sgiImage);
451 
452 	if (ret >= B_OK) {
453 
454 		bool bheaderonly = false, bdataonly = false;
455 
456 		uint32 width = sgiImage->Width();
457 		uint32 height = sgiImage->Height();
458 		uint32 channelCount = sgiImage->CountChannels();
459 		color_space format = B_RGBA32;
460 		uint32 bytesPerRow = 0;
461 		uint32 bytesPerChannel = sgiImage->BytesPerChannel();
462 
463 		if (channelCount == 1) {
464 //			format = B_GRAY8;	// this format is not supported by most applications
465 //			bytesPerRow = width;
466 			format = B_RGB32;
467 			bytesPerRow = width * 4;
468 		} else if (channelCount == 2) {
469 			// means gray (luminance) + alpha, we convert that to B_RGBA32
470 			format = B_RGBA32;
471 			bytesPerRow = width * 4;
472 		} else if (channelCount == 3) {
473 			format = B_RGB32; // should be B_RGB24, but let's not push it too hard...
474 			bytesPerRow = width * 4;
475 		} else if (channelCount == 4) {
476 			format = B_RGBA32;
477 			bytesPerRow = width * 4;
478 		} else
479 			ret = B_NO_TRANSLATOR; // we cannot handle this image
480 
481 		if (ret >= B_OK && !bdataonly) {
482 			// Construct and write Be bitmap header
483 			TranslatorBitmap bitsHeader;
484 			bitsHeader.magic = B_TRANSLATOR_BITMAP;
485 			bitsHeader.bounds.left = 0;
486 			bitsHeader.bounds.top = 0;
487 			bitsHeader.bounds.right = width - 1;
488 			bitsHeader.bounds.bottom = height - 1;
489 			bitsHeader.rowBytes = bytesPerRow;
490 			bitsHeader.colors = format;
491 			bitsHeader.dataSize = bitsHeader.rowBytes * height;
492 			if ((ret = swap_data(B_UINT32_TYPE, &bitsHeader,
493 				sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN)) < B_OK) {
494 				return ret;
495 			} else
496 				ret = outDestination->Write(&bitsHeader, sizeof(TranslatorBitmap));
497 		}
498 if (ret < B_OK)
499 printf("error writing bits header: %s\n", strerror(ret));
500 		if (ret >= B_OK && !bheaderonly) {
501 			// read one row at a time,
502 			// convert to the correct format
503 			// and write out the results
504 
505 			// SGI Images store each channel separately
506 			// a buffer is allocated big enough to hold all channels
507 			// then the pointers are assigned with offsets into that buffer
508 			uint8** rows = new(nothrow) uint8*[channelCount];
509 			if (rows)
510 				rows[0] = new(nothrow) uint8[width * channelCount * bytesPerChannel];
511 			// rowBuffer is going to hold the converted data
512 			uint8* rowBuffer = new(nothrow) uint8[bytesPerRow];
513 			if (rows && rows[0] && rowBuffer) {
514 				// assign the other pointers (channel offsets in row buffer)
515 				for (uint32 i = 1; i < channelCount; i++)
516 					rows[i] = rows[0] + i * width * bytesPerChannel;
517 				// loop through all lines of the image
518 				for (int32 y = height - 1; y >= 0 && ret >= B_OK; y--) {
519 					// fill the row buffer with each channel
520 					for (uint32 z = 0; z < channelCount; z++) {
521 						ret = sgiImage->ReadRow(rows[z], y, z);
522 						if (ret < B_OK)
523 							break;
524 					}
525 					// see if an error happened while reading
526 					if (ret < B_OK)
527 						break;
528 					// convert to native format (big endian)
529 					if (bytesPerChannel == 1) {
530 						switch (format) {
531 							case B_GRAY8: {
532 								uint8* dst = rowBuffer;
533 								for (uint32 x = 0; x < width; x++) {
534 									dst[0] = rows[0][x];
535 									dst += 1;
536 								}
537 								break;
538 							}
539 							case B_RGB24: {
540 								uint8* dst = rowBuffer;
541 								for (uint32 x = 0; x < width; x++) {
542 									dst[0] = rows[2][x];
543 									dst[1] = rows[1][x];
544 									dst[2] = rows[0][x];
545 									dst += 3;
546 								}
547 								break;
548 							}
549 							case B_RGB32: {
550 								uint8* dst = rowBuffer;
551 								if (channelCount == 1) {
552 									for (uint32 x = 0; x < width; x++) {
553 										dst[0] = rows[0][x];
554 										dst[1] = rows[0][x];
555 										dst[2] = rows[0][x];
556 										dst[3] = 255;
557 										dst += 4;
558 									}
559 								} else {
560 									for (uint32 x = 0; x < width; x++) {
561 										dst[0] = rows[2][x];
562 										dst[1] = rows[1][x];
563 										dst[2] = rows[0][x];
564 										dst[3] = 255;
565 										dst += 4;
566 									}
567 								}
568 								break;
569 							}
570 							case B_RGBA32: {
571 								uint8* dst = rowBuffer;
572 								if (channelCount == 2) {
573 									for (uint32 x = 0; x < width; x++) {
574 										dst[0] = rows[0][x];
575 										dst[1] = rows[0][x];
576 										dst[2] = rows[0][x];
577 										dst[3] = rows[1][x];
578 										dst += 4;
579 									}
580 								} else {
581 									for (uint32 x = 0; x < width; x++) {
582 										dst[0] = rows[2][x];
583 										dst[1] = rows[1][x];
584 										dst[2] = rows[0][x];
585 										dst[3] = rows[3][x];
586 										dst += 4;
587 									}
588 								}
589 								break;
590 							}
591 							default:
592 								// cannot be here
593 								break;
594 						} // switch (format)
595 						ret = outDestination->Write(rowBuffer, bytesPerRow);
596 					} else {
597 						// support for 16 bits per channel images
598 						uint16** rows16 = (uint16**)rows;
599 						switch (format) {
600 							case B_GRAY8: {
601 								uint8* dst = rowBuffer;
602 								for (uint32 x = 0; x < width; x++) {
603 									dst[0] = rows16[0][x] >> 8;
604 									dst += 1;
605 								}
606 								break;
607 							}
608 							case B_RGB24: {
609 								uint8* dst = rowBuffer;
610 								for (uint32 x = 0; x < width; x++) {
611 									dst[0] = rows16[2][x] >> 8;
612 									dst[1] = rows16[1][x] >> 8;
613 									dst[2] = rows16[0][x] >> 8;
614 									dst += 3;
615 								}
616 								break;
617 							}
618 							case B_RGB32: {
619 								uint8* dst = rowBuffer;
620 								if (channelCount == 1) {
621 									for (uint32 x = 0; x < width; x++) {
622 										dst[0] = rows16[0][x] >> 8;
623 										dst[1] = rows16[0][x] >> 8;
624 										dst[2] = rows16[0][x] >> 8;
625 										dst[3] = 255;
626 										dst += 4;
627 									}
628 								} else {
629 									for (uint32 x = 0; x < width; x++) {
630 										dst[0] = rows16[2][x] >> 8;
631 										dst[1] = rows16[1][x] >> 8;
632 										dst[2] = rows16[0][x] >> 8;
633 										dst[3] = 255;
634 										dst += 4;
635 									}
636 								}
637 								break;
638 							}
639 							case B_RGBA32: {
640 								uint8* dst = rowBuffer;
641 								if (channelCount == 2) {
642 									for (uint32 x = 0; x < width; x++) {
643 										dst[0] = rows16[0][x] >> 8;
644 										dst[1] = rows16[0][x] >> 8;
645 										dst[2] = rows16[0][x] >> 8;
646 										dst[3] = rows16[1][x] >> 8;
647 										dst += 4;
648 									}
649 								} else {
650 									for (uint32 x = 0; x < width; x++) {
651 										dst[0] = rows16[2][x] >> 8;
652 										dst[1] = rows16[1][x] >> 8;
653 										dst[2] = rows16[0][x] >> 8;
654 										dst[3] = rows16[3][x] >> 8;
655 										dst += 4;
656 									}
657 								}
658 								break;
659 							}
660 							default:
661 								// cannot be here
662 								break;
663 						} // switch (format)
664 						ret = outDestination->Write(rowBuffer, bytesPerRow);
665 					} // 16 bit version
666 				} // for (uint32 y = 0; y < height && ret >= B_OK; y++)
667 				if (ret >= B_OK)
668 					ret = B_OK;
669 			} else // if (rows && rows[0] && rowBuffer)
670 				ret = B_NO_MEMORY;
671 			delete[] rows[0];
672 			delete[] rows;
673 			delete[] rowBuffer;
674 		} // if (ret >= B_OK && !bheaderonly)
675 	} // if (ret >= B_OK)
676 	delete sgiImage;
677 
678 	return ret;
679 }
680 
681 // ---------------------------------------------------------------
682 // DerivedTranslate
683 //
684 // Translates the data in inSource to the type outType and stores
685 // the translated data in outDestination.
686 //
687 // Preconditions:
688 //
689 // Parameters:	inSource,	the data to be translated
690 //
691 //				inInfo,	hint about the data in inSource (not used)
692 //
693 //				ioExtension,	configuration options for the
694 //								translator
695 //
696 //				outType,	the type to convert inSource to
697 //
698 //				outDestination,	where the translated data is
699 //								put
700 //
701 //				baseType, indicates whether inSource is in the
702 //				          bits format, not in the bits format or
703 //				          is unknown
704 //
705 // Postconditions:
706 //
707 // Returns: B_BAD_VALUE, if the options in ioExtension are bad
708 //
709 // B_NO_TRANSLATOR, if this translator doesn't understand the data
710 //
711 // B_ERROR, if there was an error allocating memory or converting
712 //          data
713 //
714 // B_OK, if all went well
715 // ---------------------------------------------------------------
716 status_t
717 SGITranslator::DerivedTranslate(BPositionIO *inSource,
718 		const translator_info *inInfo, BMessage *ioExtension,
719 		uint32 outType, BPositionIO *outDestination, int32 baseType)
720 {
721 	if (baseType == 1)
722 		// if inSource is in bits format
723 		return translate_from_bits(inSource, outType, outDestination);
724 	else if (baseType == 0)
725 		// if inSource is NOT in bits format
726 		return translate_from_sgi(inSource, outType, outDestination);
727 	else
728 		// if BaseTranslator did not properly identify the data as
729 		// bits or not bits
730 		return B_NO_TRANSLATOR;
731 }
732 
733 BView *
734 SGITranslator::NewConfigView(TranslatorSettings *settings)
735 {
736 	return new SGIView("SGITranslator Settings", B_WILL_DRAW, settings);
737 }
738