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