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