1 /* NAME: 2 E3Texture.c 3 4 DESCRIPTION: 5 Implementation of Quesa API calls. 6 7 COPYRIGHT: 8 Copyright (c) 1999-2005, Quesa Developers. All rights reserved. 9 10 For the current release of Quesa, please see: 11 12 <http://www.quesa.org/> 13 14 Redistribution and use in source and binary forms, with or without 15 modification, are permitted provided that the following conditions 16 are met: 17 18 o Redistributions of source code must retain the above copyright 19 notice, this list of conditions and the following disclaimer. 20 21 o Redistributions in binary form must reproduce the above 22 copyright notice, this list of conditions and the following 23 disclaimer in the documentation and/or other materials provided 24 with the distribution. 25 26 o Neither the name of Quesa nor the names of its contributors 27 may be used to endorse or promote products derived from this 28 software without specific prior written permission. 29 30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 36 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 37 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 38 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 39 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 ___________________________________________________________________________ 42 */ 43 //============================================================================= 44 // Include files 45 //----------------------------------------------------------------------------- 46 #include "E3Prefix.h" 47 #include "E3Texture.h" 48 #include "E3Main.h" 49 50 51 52 53 54 //============================================================================= 55 // Internal constants 56 //----------------------------------------------------------------------------- 57 // The maximum number of mipmaps a texture may have 58 #define kQ3MaxMipmaps 32 59 60 61 62 63 64 //============================================================================= 65 // Internal types 66 //----------------------------------------------------------------------------- 67 68 69 class E3PixmapTexture : public E3Texture // This is a leaf class so no other classes use this, 70 // so it can be here in the .c file rather than in 71 // the .h file, hence all the fields can be public 72 // as nobody should be including this file 73 { 74 Q3_CLASS_ENUMS ( kQ3TextureTypePixmap, E3PixmapTexture, E3Texture ) 75 public : 76 77 TQ3StoragePixmap instanceData ; 78 } ; 79 80 81 82 class E3MipmapTexture : public E3Texture // This is a leaf class so no other classes use this, 83 // so it can be here in the .c file rather than in 84 // the .h file, hence all the fields can be public 85 // as nobody should be including this file 86 { 87 Q3_CLASS_ENUMS ( kQ3TextureTypeMipmap, E3MipmapTexture, E3Texture ) 88 public : 89 90 TQ3Mipmap instanceData ; 91 } ; 92 93 94 95 class E3CompressedPixmapTexture : public E3Texture // This is a leaf class so no other classes use this, 96 // so it can be here in the .c file rather than in 97 // the .h file, hence all the fields can be public 98 // as nobody should be including this file 99 { 100 Q3_CLASS_ENUMS ( kQ3TextureTypeCompressedPixmap, E3CompressedPixmapTexture, E3Texture ) 101 public : 102 103 TQ3CompressedPixmap instanceData ; 104 } ; 105 106 107 108 109 110 //============================================================================= 111 // Internal functions 112 //----------------------------------------------------------------------------- 113 // E3TextureInfo::E3TextureInfo : Constructor for class info of the class. 114 //----------------------------------------------------------------------------- 115 116 E3TextureInfo::E3TextureInfo ( 117 TQ3XMetaHandler newClassMetaHandler, 118 E3ClassInfo* newParent // nil for root class of course 119 ) 120 : E3SharedInfo ( newClassMetaHandler, newParent ) , 121 textureDimensions ( (TQ3XTextureDimensionsMethod) Find_Method ( kQ3XMethodTypeTextureDimensions ) ) 122 { 123 if ( textureDimensions == NULL ) 124 SetAbstract () ; 125 } ; 126 127 128 //============================================================================= 129 // e3transform_new_class_info : Method to construct a class info record. 130 //----------------------------------------------------------------------------- 131 static E3ClassInfo* 132 e3texture_new_class_info ( 133 TQ3XMetaHandler newClassMetaHandler, 134 E3ClassInfo* newParent 135 ) 136 { 137 return new ( std::nothrow ) E3TextureInfo ( newClassMetaHandler, newParent ) ; 138 } 139 140 141 142 143 144 //============================================================================= 145 // e3texture_pixmap_new : Pixmap texture new method. 146 //----------------------------------------------------------------------------- 147 static TQ3Status 148 e3texture_pixmap_new(TQ3Object theObject, void *privateData, const void *paramData) 149 { TQ3StoragePixmap * instanceData = ( TQ3StoragePixmap *) privateData ; 150 const TQ3StoragePixmap * textureData = (const TQ3StoragePixmap *) paramData ; 151 152 153 154 // Initialise our instance data 155 instanceData->width = textureData->width ; 156 instanceData->height = textureData->height ; 157 instanceData->rowBytes = textureData->rowBytes ; 158 instanceData->pixelSize = textureData->pixelSize ; 159 instanceData->pixelType = textureData->pixelType ; 160 instanceData->bitOrder = textureData->bitOrder ; 161 instanceData->byteOrder = textureData->byteOrder ; 162 163 E3Shared_Acquire(&instanceData->image, textureData->image); 164 165 return(kQ3Success) ; 166 } 167 168 169 170 171 172 //============================================================================= 173 // e3texture_pixmap_duplicate : Pixmap texture duplicate method. 174 //----------------------------------------------------------------------------- 175 static TQ3Status 176 e3texture_pixmap_duplicate( TQ3Object fromObject, const void *fromPrivateData, 177 TQ3Object toObject, void *toPrivateData) 178 { 179 const TQ3StoragePixmap * fromInstanceData = (const TQ3StoragePixmap *) fromPrivateData; 180 TQ3StoragePixmap * toInstanceData = (TQ3StoragePixmap *) toPrivateData; 181 TQ3Status qd3dStatus = kQ3Success ; 182 183 #pragma unused(fromObject) 184 #pragma unused(toObject) 185 186 187 188 // Validate our parameters 189 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromObject), kQ3Failure); 190 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromPrivateData), kQ3Failure); 191 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toObject), kQ3Failure); 192 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toPrivateData), kQ3Failure); 193 194 195 196 //duplicate the fields 197 toInstanceData->width = fromInstanceData->width ; 198 toInstanceData->height = fromInstanceData->height ; 199 toInstanceData->rowBytes = fromInstanceData->rowBytes ; 200 toInstanceData->pixelSize = fromInstanceData->pixelSize ; 201 toInstanceData->pixelType = fromInstanceData->pixelType ; 202 toInstanceData->bitOrder = fromInstanceData->bitOrder ; 203 toInstanceData->byteOrder = fromInstanceData->byteOrder ; 204 205 206 207 //duplicate the texture storage 208 toInstanceData->image = Q3Object_Duplicate( fromInstanceData->image ); 209 210 return(qd3dStatus) ; 211 } 212 213 214 215 216 217 //============================================================================= 218 // e3texture_pixmap_delete : Pixmap texture delete method. 219 //----------------------------------------------------------------------------- 220 static void 221 e3texture_pixmap_delete(TQ3Object theObject, void *privateData) 222 { TQ3StoragePixmap *instanceData = (TQ3StoragePixmap *) privateData; 223 #pragma unused(theObject) 224 225 226 227 //delete the storage for the pixmap 228 Q3Object_CleanDispose(&instanceData->image ) ; 229 } 230 231 232 233 234 235 //============================================================================= 236 // e3texture_pixmap_dimensions : Get the dimensions of the texture. 237 //----------------------------------------------------------------------------- 238 static void 239 e3texture_pixmap_dimensions ( E3PixmapTexture* texture, TQ3Point2D *theDimensions ) 240 { 241 // Return the dimensions 242 theDimensions->x = (float) texture->instanceData.width ; 243 theDimensions->y = (float) texture->instanceData.height ; 244 } 245 246 247 248 249 250 //============================================================================= 251 // e3texture_pixmap_metahandler : Pixmap texture metahandler. 252 //----------------------------------------------------------------------------- 253 static TQ3XFunctionPointer 254 e3texture_pixmap_metahandler(TQ3XMethodType methodType) 255 { 256 TQ3XFunctionPointer theMethod = NULL; 257 258 259 260 // Return our methods 261 switch (methodType) { 262 case kQ3XMethodTypeObjectNew: 263 theMethod = (TQ3XFunctionPointer) e3texture_pixmap_new; 264 break; 265 266 case kQ3XMethodTypeObjectDelete: 267 theMethod = (TQ3XFunctionPointer) e3texture_pixmap_delete; 268 break; 269 270 case kQ3XMethodTypeObjectDuplicate: 271 theMethod = (TQ3XFunctionPointer) e3texture_pixmap_duplicate; 272 break; 273 274 case kQ3XMethodTypeTextureDimensions: 275 theMethod = (TQ3XFunctionPointer) e3texture_pixmap_dimensions; 276 break; 277 } 278 279 return(theMethod); 280 } 281 282 283 284 285 286 //============================================================================= 287 // e3texture_mipmap_new : Mipxmap texture new method. 288 //----------------------------------------------------------------------------- 289 #pragma mark - 290 static TQ3Status 291 e3texture_mipmap_new(TQ3Object theObject, void *privateData, const void *paramData) 292 { 293 TQ3Mipmap * instanceData = ( TQ3Mipmap *) privateData ; 294 const TQ3Mipmap * textureData = (const TQ3Mipmap *) paramData ; 295 296 297 298 // copy the fields 299 instanceData->useMipmapping = textureData->useMipmapping ; 300 instanceData->pixelType = textureData->pixelType ; 301 instanceData->bitOrder = textureData->bitOrder ; 302 instanceData->byteOrder = textureData->byteOrder ; 303 304 305 // the reserved field should always be set to NULL 306 instanceData->reserved = textureData->reserved ; 307 308 309 //copy the mipmapImages 310 Q3Memory_Copy(&textureData->mipmaps, 311 &instanceData->mipmaps, 312 sizeof(TQ3MipmapImage) * kQ3MaxMipmaps ) ; 313 314 315 316 //set the texture storage 317 E3Shared_Acquire(&instanceData->image, textureData->image); 318 319 return(kQ3Success) ; 320 } 321 322 323 324 325 326 //============================================================================= 327 // e3texture_mipmap_duplicate : Mipmap texture duplicate method. 328 //----------------------------------------------------------------------------- 329 static TQ3Status 330 e3texture_mipmap_duplicate( TQ3Object fromObject, const void *fromPrivateData, 331 TQ3Object toObject, void *toPrivateData) 332 { 333 const TQ3Mipmap * fromInstanceData = (const TQ3Mipmap *) fromPrivateData; 334 TQ3Mipmap * toInstanceData = (TQ3Mipmap *) toPrivateData; 335 336 #pragma unused(fromObject) 337 #pragma unused(toObject) 338 339 340 341 // Validate our parameters 342 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromObject), kQ3Failure); 343 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromPrivateData), kQ3Failure); 344 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toObject), kQ3Failure); 345 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toPrivateData), kQ3Failure); 346 347 348 349 // copy the fields 350 toInstanceData->useMipmapping = fromInstanceData->useMipmapping ; 351 toInstanceData->pixelType = fromInstanceData->pixelType ; 352 toInstanceData->bitOrder = fromInstanceData->bitOrder ; 353 toInstanceData->byteOrder = fromInstanceData->byteOrder ; 354 355 356 // the reserved field should always be set to NULL 357 toInstanceData->reserved = fromInstanceData->reserved ; 358 359 360 //copy the mipmapImages 361 Q3Memory_Copy(&fromInstanceData->mipmaps, 362 &toInstanceData->mipmaps, 363 sizeof(TQ3MipmapImage) * kQ3MaxMipmaps) ; 364 365 366 367 //set the texture storage 368 toInstanceData->image = Q3Object_Duplicate( fromInstanceData->image ); 369 370 return(kQ3Success) ; 371 } 372 373 374 375 376 377 //============================================================================= 378 // e3texture_mipmap_delete : Mipmap texture delete method. 379 //----------------------------------------------------------------------------- 380 static void 381 e3texture_mipmap_delete(TQ3Object theObject, void *privateData) 382 { 383 TQ3Mipmap * instanceData = (TQ3Mipmap *) privateData; 384 #pragma unused(theObject) 385 386 387 388 //delete the storage for the mipmap 389 Q3Object_CleanDispose(&instanceData->image ) ; 390 } 391 392 393 394 395 396 //============================================================================= 397 // e3texture_mipmap_dimensions : Get the dimensions of the texture. 398 //----------------------------------------------------------------------------- 399 static void 400 e3texture_mipmap_dimensions ( E3MipmapTexture* texture, TQ3Point2D *theDimensions ) 401 { 402 // Return the dimensions 403 theDimensions->x = (float) texture->instanceData.mipmaps [ 0 ].width ; 404 theDimensions->y = (float) texture->instanceData.mipmaps [ 0 ].height ; 405 } 406 407 408 409 410 411 //============================================================================= 412 // e3texture_mipmap_metahandler : Mipmap texture metahandler. 413 //----------------------------------------------------------------------------- 414 static TQ3XFunctionPointer 415 e3texture_mipmap_metahandler(TQ3XMethodType methodType) 416 { 417 TQ3XFunctionPointer theMethod = NULL; 418 419 420 421 // Return our methods 422 switch (methodType) { 423 case kQ3XMethodTypeObjectNew: 424 theMethod = (TQ3XFunctionPointer) e3texture_mipmap_new; 425 break; 426 427 case kQ3XMethodTypeObjectDelete: 428 theMethod = (TQ3XFunctionPointer) e3texture_mipmap_delete; 429 break; 430 431 case kQ3XMethodTypeObjectDuplicate: 432 theMethod = (TQ3XFunctionPointer) e3texture_mipmap_duplicate; 433 break; 434 435 case kQ3XMethodTypeTextureDimensions: 436 theMethod = (TQ3XFunctionPointer) e3texture_mipmap_dimensions; 437 break; 438 } 439 440 return(theMethod); 441 } 442 443 444 445 446 447 //============================================================================= 448 // e3texture_compressed_new : Compressed texture new method. 449 //----------------------------------------------------------------------------- 450 #pragma mark - 451 static TQ3Status 452 e3texture_compressed_new(TQ3Object theObject, void *privateData, const void *paramData) 453 { 454 TQ3CompressedPixmap * instanceData = ( TQ3CompressedPixmap *) privateData ; 455 const TQ3CompressedPixmap * textureData = (const TQ3CompressedPixmap *) paramData ; 456 457 458 459 // copy the fields 460 instanceData->imageDescByteOrder = textureData->imageDescByteOrder ; 461 instanceData->makeMipmaps = textureData->makeMipmaps ; 462 instanceData->width = textureData->width ; 463 instanceData->height = textureData->height ; 464 instanceData->pixelSize = textureData->pixelSize ; 465 instanceData->pixelType = textureData->pixelType ; 466 467 468 469 //copy the objects - compressedImage and imageDesc 470 E3Shared_Acquire(&instanceData->compressedImage, textureData->compressedImage); 471 E3Shared_Acquire(&instanceData->imageDesc, textureData->imageDesc); 472 473 return(kQ3Success) ; 474 } 475 476 477 478 479 480 //============================================================================= 481 // e3texture_compressed_duplicate : Compressed texture duplicate method. 482 //----------------------------------------------------------------------------- 483 static TQ3Status 484 e3texture_compressed_duplicate( TQ3Object fromObject, const void *fromPrivateData, 485 TQ3Object toObject, void *toPrivateData) 486 { 487 const TQ3CompressedPixmap * fromInstanceData = (const TQ3CompressedPixmap *) fromPrivateData; 488 TQ3CompressedPixmap * toInstanceData = (TQ3CompressedPixmap *) toPrivateData; 489 490 #pragma unused(fromObject) 491 #pragma unused(toObject) 492 493 494 495 // Validate our parameters 496 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromObject), kQ3Failure); 497 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(fromPrivateData), kQ3Failure); 498 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toObject), kQ3Failure); 499 Q3_REQUIRE_OR_RESULT(Q3_VALID_PTR(toPrivateData), kQ3Failure); 500 501 502 503 // copy the fields 504 toInstanceData->imageDescByteOrder = fromInstanceData->imageDescByteOrder ; 505 toInstanceData->makeMipmaps = fromInstanceData->makeMipmaps ; 506 toInstanceData->width = fromInstanceData->width ; 507 toInstanceData->height = fromInstanceData->height ; 508 toInstanceData->pixelSize = fromInstanceData->pixelSize ; 509 toInstanceData->pixelType = fromInstanceData->pixelType ; 510 511 512 513 //copy the objects - compressedImage and imageDesc 514 E3Shared_Acquire(&toInstanceData->compressedImage, fromInstanceData->compressedImage); 515 E3Shared_Acquire(&toInstanceData->imageDesc, fromInstanceData->imageDesc); 516 517 return(kQ3Success) ; 518 } 519 520 521 522 523 524 //============================================================================= 525 // e3texture_compressed_delete : Compressed texture delete method. 526 //----------------------------------------------------------------------------- 527 static void 528 e3texture_compressed_delete(TQ3Object theObject, void *privateData) 529 { 530 TQ3CompressedPixmap * instanceData = (TQ3CompressedPixmap *) privateData; 531 #pragma unused(theObject) 532 533 534 535 //delete the storage for the compressed image 536 Q3Object_CleanDispose(&instanceData->compressedImage ) ; 537 538 539 540 //delete the storge for the imageDesc 541 Q3Object_CleanDispose(&instanceData->imageDesc ) ; 542 } 543 544 545 546 547 548 //============================================================================= 549 // e3texture_compressed_dimensions : Get the dimensions of the texture. 550 //----------------------------------------------------------------------------- 551 static void 552 e3texture_compressed_dimensions ( E3CompressedPixmapTexture* texture, TQ3Point2D *theDimensions ) 553 { 554 // Return the dimensions 555 theDimensions->x = (float) texture->instanceData.width ; 556 theDimensions->y = (float) texture->instanceData.height ; 557 } 558 559 560 561 562 563 //============================================================================= 564 // e3texture_compressed_metahandler : Compressed texture metahandler. 565 //----------------------------------------------------------------------------- 566 static TQ3XFunctionPointer 567 e3texture_compressed_metahandler(TQ3XMethodType methodType) 568 { 569 TQ3XFunctionPointer theMethod = NULL; 570 571 572 573 // Return our methods 574 switch (methodType) { 575 case kQ3XMethodTypeObjectNew: 576 theMethod = (TQ3XFunctionPointer) e3texture_compressed_new; 577 break; 578 579 case kQ3XMethodTypeObjectDelete: 580 theMethod = (TQ3XFunctionPointer) e3texture_compressed_delete; 581 break; 582 583 case kQ3XMethodTypeObjectDuplicate: 584 theMethod = (TQ3XFunctionPointer) e3texture_compressed_duplicate; 585 break; 586 587 case kQ3XMethodTypeTextureDimensions: 588 theMethod = (TQ3XFunctionPointer) e3texture_compressed_dimensions; 589 break; 590 } 591 592 return(theMethod); 593 } 594 595 596 597 598 599 //============================================================================= 600 // e3texture_metahandler : base metahandler for textures. 601 //----------------------------------------------------------------------------- 602 static TQ3XFunctionPointer 603 e3texture_metahandler(TQ3XMethodType methodType) 604 { 605 // Return our methods 606 switch ( methodType ) 607 { 608 case kQ3XMethodTypeNewObjectClass : 609 return (TQ3XFunctionPointer) e3texture_new_class_info ; 610 611 } 612 613 return NULL ; 614 } 615 616 617 618 619 620 //============================================================================= 621 // Public functions 622 //----------------------------------------------------------------------------- 623 // E3Texture_RegisterClass : Register the texture classes. 624 //----------------------------------------------------------------------------- 625 #pragma mark - 626 TQ3Status 627 E3Texture_RegisterClass(void) 628 { TQ3Status qd3dStatus = kQ3Success; 629 630 631 632 // register the texture base class 633 if(qd3dStatus == kQ3Success) 634 qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameTexture, 635 e3texture_metahandler, 636 E3Texture ) ; 637 638 639 // register pixmap texture 640 if(qd3dStatus == kQ3Success) 641 qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameTexturePixmap, 642 e3texture_pixmap_metahandler, 643 E3PixmapTexture ) ; 644 645 646 // register mipmap texture 647 if(qd3dStatus == kQ3Success) 648 qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameTextureMipmap, 649 e3texture_mipmap_metahandler, 650 E3MipmapTexture ) ; 651 652 653 // register compressed texture 654 if(qd3dStatus == kQ3Success) 655 qd3dStatus = Q3_REGISTER_CLASS ( kQ3ClassNameTextureCompressed, 656 e3texture_compressed_metahandler, 657 E3CompressedPixmapTexture ) ; 658 659 return(qd3dStatus) ; 660 } 661 662 663 664 665 666 //============================================================================= 667 // E3Texture_UnregisterClass : Unregister the texture classes. 668 //----------------------------------------------------------------------------- 669 TQ3Status 670 E3Texture_UnregisterClass(void) 671 { 672 TQ3Status qd3dStatus ; 673 674 675 676 // Unregister the classes 677 qd3dStatus = E3ClassTree::UnregisterClass(kQ3TextureTypeCompressedPixmap, kQ3True) ; 678 qd3dStatus = E3ClassTree::UnregisterClass(kQ3TextureTypeMipmap, kQ3True) ; 679 qd3dStatus = E3ClassTree::UnregisterClass(kQ3TextureTypePixmap, kQ3True) ; 680 qd3dStatus = E3ClassTree::UnregisterClass(kQ3SharedTypeTexture, kQ3True ) ; 681 682 return(qd3dStatus) ; 683 } 684 685 686 687 688 689 //============================================================================= 690 // E3Texture_GetType : Get the type of a texture object. 691 //----------------------------------------------------------------------------- 692 #pragma mark - 693 TQ3ObjectType 694 E3Texture_GetType(TQ3TextureObject texture) 695 { 696 // Return the type of the texture 697 return texture->GetObjectType ( kQ3SharedTypeTexture ) ; 698 } 699 700 701 702 703 //============================================================================= 704 // E3Texture_IsOfMyClass : Check if object pointer is valid and of type texture 705 //----------------------------------------------------------------------------- 706 // Replaces Q3Object_IsType ( object, kQ3SharedTypeTexture ) 707 // but call is smaller and does not call E3System_Bottleneck 708 // as this is (always?) done in the calling code as well 709 //----------------------------------------------------------------------------- 710 TQ3Boolean 711 E3Texture_IsOfMyClass ( TQ3Object object ) 712 { 713 return ( (object != NULL) && object->IsObjectValid() && 714 Q3_OBJECT_IS_CLASS( object, E3Texture ) )? 715 kQ3True : kQ3False; 716 } 717 718 719 720 721 722 //============================================================================= 723 // E3Texture_GetWidth : Get the width of the texture in pixels. 724 //----------------------------------------------------------------------------- 725 TQ3Status 726 E3Texture::GetWidth ( TQ3Uns32* width ) 727 { 728 // Get the texture width 729 TQ3Point2D theDimensions ; 730 GetClass ()->textureDimensions ( this, &theDimensions ) ; 731 732 *width = (TQ3Uns32) theDimensions.x ; 733 734 return kQ3Success ; 735 } 736 737 738 739 740 741 //============================================================================= 742 // E3Texture_GetHeight : Get the height of a texture in pixels. 743 //----------------------------------------------------------------------------- 744 TQ3Status 745 E3Texture::GetHeight ( TQ3Uns32* height ) 746 { 747 // Get the texture height 748 TQ3Point2D theDimensions ; 749 GetClass ()->textureDimensions ( this, &theDimensions ) ; 750 751 *height = (TQ3Uns32) theDimensions.y ; 752 753 return kQ3Success ; 754 } 755 756 757 758 759 760 //============================================================================= 761 // E3PixmapTexture_New : Create a new PixmapTexture. 762 //----------------------------------------------------------------------------- 763 #pragma mark - 764 TQ3TextureObject 765 E3PixmapTexture_New(const TQ3StoragePixmap *pixmap) 766 { 767 // Create the object 768 return E3ClassTree::CreateInstance ( kQ3TextureTypePixmap, kQ3False, pixmap ) ; 769 } 770 771 772 773 774 775 //============================================================================= 776 // E3PixmapTexture_GetPixmap : Get the pixmap of a pixmap texture. 777 //----------------------------------------------------------------------------- 778 TQ3Status 779 E3PixmapTexture_GetPixmap(TQ3TextureObject theTexture, TQ3StoragePixmap *pixmap) 780 { 781 E3PixmapTexture* texture = (E3PixmapTexture*) theTexture ; 782 783 784 785 //get the fields of the pixmap storage 786 pixmap->width = texture->instanceData.width ; 787 pixmap->height = texture->instanceData.height ; 788 pixmap->rowBytes = texture->instanceData.rowBytes ; 789 pixmap->pixelSize = texture->instanceData.pixelSize ; 790 pixmap->pixelType = texture->instanceData.pixelType ; 791 pixmap->bitOrder = texture->instanceData.bitOrder ; 792 pixmap->byteOrder = texture->instanceData.byteOrder ; 793 794 //get the image data 795 E3Shared_Acquire ( & pixmap->image, texture->instanceData.image) ; 796 797 return kQ3Success ; 798 } 799 800 801 802 803 804 //============================================================================= 805 // E3PixmapTexture_SetPixmap : Set the pixmap of a pixmap texture. 806 //----------------------------------------------------------------------------- 807 TQ3Status 808 E3PixmapTexture_SetPixmap(TQ3TextureObject theTexture, const TQ3StoragePixmap *pixmap) 809 { 810 E3PixmapTexture* texture = (E3PixmapTexture*) theTexture ; 811 812 813 //set the fields of the pixmap storage 814 texture->instanceData.width = pixmap->width ; 815 texture->instanceData.height = pixmap->height ; 816 texture->instanceData.rowBytes = pixmap->rowBytes ; 817 texture->instanceData.pixelSize = pixmap->pixelSize ; 818 texture->instanceData.pixelType = pixmap->pixelType ; 819 texture->instanceData.bitOrder = pixmap->bitOrder ; 820 texture->instanceData.byteOrder = pixmap->byteOrder ; 821 822 //set the image data 823 E3Shared_Replace ( & texture->instanceData.image, pixmap->image ) ; 824 825 Q3Shared_Edited ( texture ) ; 826 827 return kQ3Success ; 828 } 829 830 831 832 833 834 //============================================================================= 835 // E3MipmapTexture_New : Create a new mipmap texture. 836 //----------------------------------------------------------------------------- 837 #pragma mark - 838 TQ3TextureObject 839 E3MipmapTexture_New(const TQ3Mipmap *mipmap) 840 { 841 // Create the object 842 return E3ClassTree::CreateInstance ( kQ3TextureTypeMipmap, kQ3False, mipmap ) ; 843 } 844 845 846 847 848 849 //============================================================================= 850 // E3MipmapTexture_GetMipmap : Get the mipmap of a mipmap texture. 851 //----------------------------------------------------------------------------- 852 TQ3Status 853 E3MipmapTexture_GetMipmap(TQ3TextureObject theTexture, TQ3Mipmap *mipmap) 854 { 855 E3MipmapTexture* texture = (E3MipmapTexture*) theTexture ; 856 857 858 859 // copy the fields 860 mipmap->useMipmapping = texture->instanceData.useMipmapping ; 861 mipmap->pixelType = texture->instanceData.pixelType ; 862 mipmap->bitOrder = texture->instanceData.bitOrder ; 863 mipmap->byteOrder = texture->instanceData.byteOrder ; 864 865 866 867 // the reserved field should always be set to NULL 868 mipmap->reserved = texture->instanceData.reserved ; 869 870 871 872 //copy the mipmapImages 873 Q3Memory_Copy ( & texture->instanceData.mipmaps, 874 & mipmap->mipmaps, 875 sizeof ( TQ3MipmapImage ) * kQ3MaxMipmaps ) ; 876 877 878 879 // get the texture storage 880 E3Shared_Acquire ( & mipmap->image, texture->instanceData.image ) ; 881 882 return kQ3Success ; 883 } 884 885 886 887 888 889 //============================================================================= 890 // E3MipmapTexture_SetMipmap : Set the mipmap of a mipmap texture. 891 //----------------------------------------------------------------------------- 892 TQ3Status 893 E3MipmapTexture_SetMipmap(TQ3TextureObject theTexture, const TQ3Mipmap *mipmap) 894 { 895 E3MipmapTexture* texture = (E3MipmapTexture*) theTexture ; 896 897 898 899 // copy the fields 900 texture->instanceData.useMipmapping = mipmap->useMipmapping ; 901 texture->instanceData.pixelType = mipmap->pixelType ; 902 texture->instanceData.bitOrder = mipmap->bitOrder ; 903 texture->instanceData.byteOrder = mipmap->byteOrder ; 904 905 906 907 // the reserved field should always be set to NULL 908 texture->instanceData.reserved = mipmap->reserved ; 909 910 911 912 //copy the mipmapImages 913 Q3Memory_Copy ( & mipmap->mipmaps, 914 & texture->instanceData.mipmaps, 915 sizeof ( TQ3MipmapImage ) * kQ3MaxMipmaps ) ; 916 917 918 919 // set the texture storage 920 E3Shared_Replace ( & texture->instanceData.image, mipmap->image ) ; 921 922 Q3Shared_Edited ( texture ) ; 923 924 return kQ3Success ; 925 } 926 927 928 929 930 931 //============================================================================= 932 // E3CompressedPixmapTexture_New : Create a new compressed pixmap texture. 933 //----------------------------------------------------------------------------- 934 #pragma mark - 935 936 #if QUESA_SUPPORT_QUICKTIME 937 938 TQ3TextureObject 939 E3CompressedPixmapTexture_New(const TQ3CompressedPixmap *compressedPixmap) 940 { 941 // Create the object 942 return E3ClassTree::CreateInstance ( kQ3TextureTypeCompressedPixmap, kQ3False, compressedPixmap ) ; 943 } 944 945 #endif // QUESA_SUPPORT_QUICKTIME 946 947 948 949 950 951 //============================================================================= 952 // E3CompressedPixmapTexture_GetCompressedPixmap : Get the compressed 953 // texture of a compressed 954 // pixmap texture. 955 //----------------------------------------------------------------------------- 956 #if QUESA_SUPPORT_QUICKTIME 957 TQ3Status 958 E3CompressedPixmapTexture_GetCompressedPixmap( TQ3TextureObject theTexture, 959 TQ3CompressedPixmap *compressedPixmap) 960 { 961 E3CompressedPixmapTexture* texture = (E3CompressedPixmapTexture*) theTexture ; 962 963 964 965 // get the fields 966 compressedPixmap->imageDescByteOrder = texture->instanceData.imageDescByteOrder ; 967 compressedPixmap->makeMipmaps = texture->instanceData.makeMipmaps ; 968 compressedPixmap->width = texture->instanceData.width ; 969 compressedPixmap->height = texture->instanceData.height ; 970 compressedPixmap->pixelSize = texture->instanceData.pixelSize ; 971 compressedPixmap->pixelType = texture->instanceData.pixelType ; 972 973 974 975 //copy the objects - compressedImage and imageDesc 976 E3Shared_Acquire ( & compressedPixmap->compressedImage, texture->instanceData.compressedImage ) ; 977 E3Shared_Acquire ( & compressedPixmap->imageDesc, texture->instanceData.imageDesc ) ; 978 979 return kQ3Success ; 980 } 981 982 #endif // QUESA_SUPPORT_QUICKTIME 983 984 985 986 987 988 //============================================================================= 989 // E3CompressedPixmapTexture_SetCompressedPixmap : Set the compressed 990 // texture of a compressed 991 // pixmap texture. 992 //----------------------------------------------------------------------------- 993 #if QUESA_SUPPORT_QUICKTIME 994 995 TQ3Status 996 E3CompressedPixmapTexture_SetCompressedPixmap( TQ3TextureObject theTexture, 997 const TQ3CompressedPixmap *compressedPixmap) 998 { 999 E3CompressedPixmapTexture* texture = (E3CompressedPixmapTexture*) theTexture ; 1000 1001 1002 1003 // get the fields 1004 texture->instanceData.imageDescByteOrder = compressedPixmap->imageDescByteOrder ; 1005 texture->instanceData.makeMipmaps = compressedPixmap->makeMipmaps ; 1006 texture->instanceData.width = compressedPixmap->width ; 1007 texture->instanceData.height = compressedPixmap->height ; 1008 texture->instanceData.pixelSize = compressedPixmap->pixelSize ; 1009 texture->instanceData.pixelType = compressedPixmap->pixelType ; 1010 1011 1012 1013 //copy the objects - compressedImage and imageDesc 1014 E3Shared_Replace ( & texture->instanceData.compressedImage, compressedPixmap->compressedImage ) ; 1015 E3Shared_Replace ( & texture->instanceData.imageDesc, compressedPixmap->imageDesc ) ; 1016 1017 Q3Shared_Edited ( texture ) ; 1018 1019 return kQ3Success ; 1020 } 1021 1022 #endif // QUESA_SUPPORT_QUICKTIME 1023 1024 1025 1026 1027 1028 //============================================================================= 1029 // E3CompressedPixmapTexture_CompressImage : Take a Pixmap and compress. 1030 //----------------------------------------------------------------------------- 1031 // Note : Compress the uncompressed sourcePixmap using codecType with 1032 // codecComponetn and codecQuality. 1033 // 1034 // codedDepth is the QuickTime bit depth of the image 1035 // 1036 // If this function succeeds in compressing sourcePixmap, it saves 1037 // the reference to the storage objects in the compressedImage and 1038 // imageDesc fields of the TQ3CompressedPixmap structure. 1039 // 1040 // The other fields are not initialised (as per the docs). 1041 //----------------------------------------------------------------------------- 1042 #if QUESA_SUPPORT_QUICKTIME 1043 1044 TQ3Status 1045 E3CompressedPixmapTexture_CompressImage(TQ3CompressedPixmap * compressedPixmap, 1046 PixMapHandle sourcePixMap, 1047 CodecType codecType, 1048 CodecComponent codecComponent, 1049 TQ3Int16 codedDepth, 1050 CodecQ codecQuality) 1051 { 1052 1053 1054 // If we support QuickTime, compress the image 1055 ImageDescriptionHandle imageDescH = NULL; 1056 long maxCompressedSize = 0; 1057 Handle compressedDataH = NULL; 1058 Ptr compressedDataP = NULL; 1059 OSErr theErr = noErr; 1060 Rect bounds = (**sourcePixMap).bounds; 1061 TQ3StorageObject compressedImage = NULL; 1062 TQ3StorageObject imageDesc = NULL; 1063 1064 1065 1066 // Make sure QuickTime is present 1067 if ((TQ3Uns32) EnterMovies == (TQ3Uns32) kUnresolvedCFragSymbolAddress) 1068 return(kQ3Failure); 1069 1070 1071 1072 theErr = GetMaxCompressionSize( sourcePixMap, 1073 &bounds, 1074 codedDepth, 1075 codecQuality, 1076 codecType, 1077 (CompressorComponent)codecComponent, 1078 &maxCompressedSize); 1079 1080 if ( theErr != noErr ) 1081 { 1082 // paramErr or noCodecErr 1083 E3ErrorManager_PostError( kQ3ErrorInvalidParameter, kQ3False ) ; 1084 1085 // failure 1086 return(kQ3Failure); 1087 } 1088 1089 // allocate memory - we need to use Mac OS Handles for QuickTime 1090 imageDescH = (ImageDescriptionHandle) NewHandle( 4 ); 1091 compressedDataH = NewHandle( maxCompressedSize ); 1092 1093 if ( compressedDataH != NULL && imageDescH != NULL ) 1094 { 1095 MoveHHi(compressedDataH); 1096 HLock(compressedDataH); 1097 compressedDataP = *compressedDataH; 1098 1099 theErr = FCompressImage(sourcePixMap, 1100 &bounds, 1101 codedDepth, 1102 codecQuality, 1103 codecType, 1104 (CompressorComponent) codecComponent, 1105 NULL, 1106 0, 1107 0, 1108 NULL, 1109 NULL, 1110 imageDescH, 1111 compressedDataP); 1112 1113 if ( theErr != noErr ) 1114 { 1115 // post error 1116 if (MemError() != noErr) 1117 E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ; 1118 else 1119 E3ErrorManager_PostError( kQ3ErrorInvalidParameter , kQ3False ) ; 1120 1121 //deallocate handle storage 1122 DisposeHandle( (Handle)imageDescH); 1123 DisposeHandle( compressedDataH); 1124 1125 // failure 1126 return(kQ3Failure) ; 1127 } 1128 1129 } 1130 // otherwise we have a memory error 1131 else 1132 { 1133 // deallocate handle storage 1134 if (imageDescH) 1135 DisposeHandle( (Handle)imageDescH); 1136 if (compressedDataH) 1137 DisposeHandle( compressedDataH); 1138 1139 // post error 1140 E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ; 1141 1142 //failure 1143 return( kQ3Failure) ; 1144 1145 } 1146 1147 1148 if (imageDescH) 1149 DisposeHandle( (Handle)imageDescH); 1150 if (compressedDataH) 1151 DisposeHandle( compressedDataH); 1152 1153 // lock the image desc handle 1154 HLock( (Handle) imageDescH ) ; 1155 1156 // store the data in storage objects 1157 compressedImage = Q3MemoryStorage_New( (unsigned char *) compressedDataP, 1158 (TQ3Uns32) (**imageDescH).dataSize ) ; 1159 imageDesc = Q3MemoryStorage_New( (unsigned char *) imageDescH, 1160 (TQ3Uns32) (**imageDescH).idSize ) ; 1161 1162 1163 // make sure memory was allocated 1164 if( compressedImage == NULL && imageDesc == NULL ) 1165 { 1166 if( compressedImage != NULL ) 1167 Q3Object_Dispose( compressedImage ) ; 1168 if( imageDesc != NULL ) 1169 Q3Object_Dispose( imageDesc ) ; 1170 1171 // deallocate handle storage 1172 DisposeHandle( (Handle) imageDescH ) ; 1173 DisposeHandle( compressedDataH ) ; 1174 1175 // we don't need to post a memory error because it 1176 // has already been done, return failure 1177 return(kQ3Failure); 1178 } 1179 1180 1181 // store the data in the compressed pixmap structure 1182 E3Shared_Acquire(&compressedPixmap->compressedImage, compressedImage); 1183 E3Shared_Acquire(&compressedPixmap->imageDesc, imageDesc); 1184 1185 // NOTE: we do not fill out the other fields of the data structure, 1186 // since this is the defined QD3D behaviour 1187 1188 // deallocate handle storage 1189 DisposeHandle( (Handle) imageDescH ) ; 1190 DisposeHandle( compressedDataH ) ; 1191 1192 return(kQ3Success) ; 1193 } 1194 1195 #endif // QUESA_SUPPORT_QUICKTIME 1196 1197 1198 1199 1200 1201 1202