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