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