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