Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CAT/CATImage.h Source File

CATImage.h

Go to the documentation of this file.
00001 /// \file    CATImage.h
00002 /// \brief   PNG image class
00003 /// \ingroup CAT
00004 ///
00005 /// Copyright (c) 2003-2008 by Michael Ellison.
00006 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00007 ///
00008 // $Author: mikeellison $
00009 // $Date: 2008-01-21 08:33:12 -0600 (Mon, 21 Jan 2008) $
00010 // $Revision:   $
00011 // $NoKeywords: $
00012 //
00013 #ifndef _CATImage_H_
00014 #define _CATImage_H_
00015 
00016 #include "CATInternal.h"
00017 #include "CATStream.h"
00018 #include "CATColor.h"
00019 #include "CATRect.h"
00020 #include "png.h"
00021 
00022 /// \class CATImage
00023 /// \brief Base image class
00024 /// \ingroup CAT
00025 ///
00026 /// All images are 32-bit R,G,B,A. This interface provides the basics
00027 /// needed for working with the images. 
00028 ///
00029 /// Note: Alpha channels are stored where 255 means opaque, and
00030 ///       0 is totally translucent.  Make sure to set this when
00031 ///       loading / building images.
00032 ///
00033 class CATImage
00034 {
00035    public:                             
00036       /// Eventually, this may specify file format.
00037       ///
00038       /// Currently, we only support PNG with RGB/Alpha channels.
00039       enum CATIMAGEFORMAT
00040       {
00041          CATIMAGE_PNG_RGBA32
00042       };
00043 
00044       /// Load() loads an image from a file.
00045       ///
00046       /// Currently, only .PNG is supported. Images are converted
00047       /// into 32-bit RGBA (8-bits per channel)
00048       ///
00049       /// Call CATImage::ReleaseImage() when done with the returned image.
00050       ///
00051       /// \param stream - an opened stream to load the image from.
00052       ///                 The stream should be positioned at the 
00053       ///                 start of the image.
00054       ///
00055       /// \param image - image ref set to image from stream on success.
00056       /// \return CATResult - CAT_SUCCESS on success.
00057       static CATResult Load             (  CATStream*         stream,
00058                                            CATImage*&         image);
00059       
00060       /// Save() saves an image to a .png file.
00061       ///
00062       /// Currently, only .PNG format is supported. Images are
00063       /// saved as 32-bit RGBA (8-bits per channel).
00064       ///
00065       /// \param stream - an opened stream to save the image to.
00066       ///                 The stream should be positioned to the location
00067       ///                 to save the image to, and it must be writeable.
00068       ///
00069       /// \param image - ptr to image to save.
00070       /// \param imageFormat - right now, doesn't do anything. Should 
00071       ///                      always be CATIMAGE_PNG_RGBA32.
00072       ///
00073       /// \return CATResult - CAT_SUCCESS on success.      
00074       static CATResult Save(  CATStream*         stream,
00075                               CATImage*          image,
00076                               CATIMAGEFORMAT     imageFormat = CATIMAGE_PNG_RGBA32);
00077 
00078       static CATResult Save(  const CATWChar*    filename,
00079                               CATImage*          image);
00080 
00081       /// CreateImage() creates an image.
00082       ///
00083       /// Use this instead of new to create image objects.
00084       /// If width and height are non-zero, creates the appropriate memory for
00085       /// the image and adds a reference. Otherwise, does not create memory 
00086       /// buffer or add reference.
00087       ///
00088       /// Call CATImage::ReleaseImage() on the returned image when done.
00089       ///
00090       /// \param image - uninitialized image ptr. Set on return.
00091       /// \param width - desired width of image in pixels.
00092       /// \param height - desired height of image in pixels.
00093       /// \param init - if true, image data is set to 0.
00094       /// \param transparent - if false, sets all alpha channels 
00095       ///                      to 255 (opaque). Otherwise, sets the
00096       ///                      alpha channels to 0 (transparent).  
00097       ///                      Ignored if init == false.    
00098       ///
00099       /// \return CATResult result code 
00100       /// \sa CATImage::ReleaseImage()
00101       static CATResult CreateImage      (  CATImage*&      image,
00102                                            CATInt32        width,
00103                                            CATInt32        height,
00104                                            bool            init = true,
00105                                            bool            transparent = true);
00106 
00107 
00108       static CATResult CreateImageFromDIB(  CATImage*&      image,
00109                                             HBITMAP         dibSection);
00110 
00111       /// ReleaseImage decrements the reference count of an image and
00112       /// will free the image if it hits zero.
00113       /// It may also free parent images if the specified
00114       /// image holds the last reference to a parent.
00115       ///
00116       /// \param image - pointer to image to release. Is set to NULL
00117       ///                if last reference was deleted.
00118       /// 
00119       /// \return CATResult result code 
00120       /// \sa CATImage::CreateImage()
00121       static CATResult ReleaseImage     (  CATImage*&         image );
00122 
00123 
00124       /// CreateSub creates a sub-image of the specified parent.
00125       ///
00126       /// dstImage should not be instantiated prior to calling CreateSub.
00127       /// Sub image is returned in dstImage.
00128       ///
00129       /// The sub image references the parent's fData
00130       /// member, and the parent image must not be deleted before you
00131       /// are done using the sub image.
00132       ///
00133       /// You may create a sub image of a sub image, ad infinum. It'll
00134       /// handle the offsets.  Call CATImage::ReleaseImage() when done.
00135       ///
00136       /// \param orgImg - parent image to derive subimage from.
00137       /// \param dstImg - uninitialized image ptr. Set on return.
00138       /// \param xOffset - relative x offset for top-left of sub image.
00139       /// \param yOffset - relative y offset for top-left of sub image.
00140       /// \param width - width of sub image.
00141       /// \param height - height of sub image.
00142       ///
00143       /// \return CATResult result code 
00144       /// \sa CATImage::ReleaseImage()
00145       /// \sa CATImage::SetSubPosition()
00146       static CATResult CreateSub       (  const CATImage*    orgImg,
00147                                           CATImage*&         dstImg,
00148                                           CATInt32               xOffset,
00149                                           CATInt32               yOffset,
00150                                           CATInt32               width,
00151                                           CATInt32               height);
00152 
00153       /// CopyImage() creates a new image and stores it in dstImg.  
00154       /// The data from srcImg is copied into a buffer owned by 
00155       /// dstImg. 
00156       ///
00157       /// Caller must call CATImage::ReleaseImage() on the returned 
00158       /// image when done.
00159       ///
00160       /// \param srcImg - source image to copy from
00161       /// \param dstImg - uninitizlied image ptr. Contains copy
00162       ///                 of srcImg on return.
00163       ///
00164       /// \return CATResult result code 
00165       /// \sa CATImage::ReleaseImage()
00166       static CATResult CopyImage        (  const CATImage*    srcImg,
00167                                            CATImage*&         dstImg);
00168       
00169       /// CopyImage() creates a new image of the same type as srcImg
00170       /// and stores it in dstImg.  The data from srcImg is
00171       /// copied into a buffer owned by dstImg. 
00172       ///
00173       /// Caller must call CATImage::ReleaseImage() on the returned 
00174       /// image when done.
00175       ///
00176       /// This version allows you to specify offsets, width, and
00177       /// height of the data to copy into a new image.
00178       /// 
00179       /// \param srcImg - source image to copy from
00180       /// \param dstImg - uninitialized image ptr. Contains copy
00181       ///                 of srcImg on return.
00182       /// \param xOffset - relative x offset for top-left of copy.
00183       /// \param yOffset - relative y offset for top-left of copy.
00184       /// \param width - width of destination image.
00185       /// \param height - height of destination image.
00186       ///
00187       /// \return CATResult result code 
00188       /// \sa CATImage::ReleaseImage()
00189       static CATResult CopyImage       (  const CATImage*    srcImg,
00190                                           CATImage*&         dstImg,
00191                                           CATInt32               xOffset,
00192                                           CATInt32               yOffset,
00193                                           CATInt32               width,
00194                                           CATInt32               height);
00195 
00196       /// CopyOver() copies from another image over the current image
00197       /// at the specified offsets for the specified width and height.
00198       ///
00199       /// If no width/height parameters are given, the entire width
00200       /// and/or height are used.
00201       ///
00202       /// Clipping is not performed. However, if the copy would go out
00203       /// of bounds, an error will be returned and the copy will not
00204       /// be performed.
00205       ///
00206       /// \param srcImg - source image to copy from
00207       /// \param dstOffsetX - x offset in dest image to copy to
00208       /// \param dstOffsetY - y offset in dest image to copy to
00209       /// \param srcOffsetX - x offset in src image to copy from
00210       /// \param srcOffsetY - y offset in src image to copy from
00211       /// \param width    - width to copy in
00212       /// \param height   - height to copy in
00213       /// \return CATResult - CAT_SUCCESS on success.
00214       CATResult  CopyOver (   const CATImage*    srcImg,
00215                               CATInt32               dstOffsetX,
00216                               CATInt32               dstOffsetY,
00217                               CATInt32               srcOffsetX,
00218                               CATInt32               srcOffsetY,
00219                               CATInt32               width  = 0,
00220                               CATInt32               height = 0);
00221 
00222       /// CopyOutBGR() copies the RGB data from a rectangle
00223       /// into a buffer and flips the Red and Blue channels.  
00224       /// The buffer must be width*height*3
00225       /// bytes in size.
00226       ///
00227       /// \param rgbBuf - raw rgb buffer of width/height size
00228       /// \param offsetX - x offset to copy from
00229       /// \param offsetY - y offset to copy from
00230       /// \param width    - width to copy 
00231       /// \param height   - height to copy 
00232       /// \param widthBytes - width of line in bytes (w/pad)
00233       /// \return CATResult - CAT_SUCCESS on success.
00234       CATResult  CopyOutBGR ( CATUInt8*              rgbBuf,
00235                               CATInt32               offsetX,
00236                               CATInt32               offsetY,
00237                               CATInt32               width,
00238                               CATInt32               height,
00239                               CATInt32               widthBytes);
00240 
00241       /// Overlay() merges from another image over the current image
00242       /// at the specified offsets for the specified width and height.
00243       ///
00244       /// If no width/height parameters are given, the entire width
00245       /// and/or height are used.
00246       ///
00247       /// Clipping is not performed. However, if the copy would go out
00248       /// of bounds, an error will be returned and the copy will not
00249       /// be performed.
00250       ///
00251       /// The alpha channel is used for the merge operation from the
00252       /// source image only.  The destination's alpha remains 
00253       /// unaffected - the alpha is used for merging the colors only.
00254       ///
00255       /// \param srcImg - source image to copy from
00256       /// \param dstOffsetX  - offset in dest image to copy to
00257       /// \param dstOffsetY  - offset in dest image to copy to
00258       /// \param srcOffsetX  - offset in src image to copy from
00259       /// \param srcOffsetY  - offset in src image to copy from
00260       /// \param width    - width to copy in
00261       /// \param height   - height to copy in
00262       /// \return CATResult - CAT_SUCCESS on success.
00263       CATResult Overlay(   const CATImage*    srcImg,
00264                            CATInt32               dstOffsetX,
00265                            CATInt32               dstOffsetY,
00266                            CATInt32               srcOffsetX,
00267                            CATInt32               srcOffsetY,
00268                            CATInt32               width  = 0,
00269                            CATInt32               height = 0);
00270       
00271 
00272       /// GetPixel() retrieves the red, green, blue, and alpha values for a 
00273       /// specified pixel.
00274       ///
00275       /// This is for convenience and prototyping - for high-speed image
00276       /// processing you'll need to work more directly with the image
00277       /// buffer.
00278       ///
00279       /// \param x - x position within the image of the pixel
00280       /// \param y - y position within the image of the pixel
00281       /// \param r - receives the red value of the pixel
00282       /// \param g - receives the green value of the pixel
00283       /// \param b - receives the blue value of the pixel
00284       /// \param a - receives the alpha values of the pixel
00285       ///
00286       /// \return CATResult result code.  CAT_SUCCESS on success.
00287       /// \sa SetPixel()
00288       CATResult GetPixel(CATInt32              x,
00289                          CATInt32              y,
00290                          unsigned char&   r,
00291                          unsigned char&   g,
00292                          unsigned char&   b,
00293                          unsigned char&   a)  const;
00294 
00295       /// GetPixel() retrieves the red, green, blue, and alpha values for a 
00296       /// specified pixel.
00297       ///
00298       /// This is for convenience and prototyping - for high-speed image
00299       /// processing you'll need to work more directly with the image
00300       /// buffer.
00301       ///
00302       /// \param x - x position within the image of the pixel
00303       /// \param y - y position within the image of the pixel
00304       /// \param color - receives the color of the pixel
00305       ///
00306       /// \return CATResult result code.  CAT_SUCCESS on success.
00307       /// \sa SetPixel()
00308       CATResult GetPixel( CATInt32              x,
00309                           CATInt32              y,
00310                           CATColor&         color)  const;
00311  
00312       /// SetPixel() sets the red, green, blue, and alpha values for a 
00313       /// specified pixel.
00314       ///
00315       /// This is for convenience and prototyping - for high-speed image
00316       /// processing you'll need to work more directly with the image
00317       /// buffer.
00318       ///
00319       /// \param x - x position within the image of the pixel
00320       /// \param y - y position within the image of the pixel
00321       /// \param r - red value of the pixel
00322       /// \param g - green value of the pixel
00323       /// \param b - blue value of the pixel
00324       /// \param a - alpha value of the pixel (255 = opaque, 0 = transparent)
00325       ///
00326       /// \return CATResult result code.  CAT_SUCCESS on success.
00327       /// \sa GetPixel()
00328       CATResult SetPixel       (  CATInt32            x,
00329                                   CATInt32            y,
00330                                   unsigned char  r,
00331                                   unsigned char  g,
00332                                   unsigned char  b,
00333                                   unsigned char  a = 255);
00334                                  
00335       /// SetPixel() sets the red, green, blue, and alpha values for a 
00336       /// specified pixel.
00337       ///
00338       /// This is for convenience and prototyping - for high-speed image
00339       /// processing you'll need to work more directly with the image
00340       /// buffer.
00341       ///
00342       /// \param x - x position within the image of the pixel
00343       /// \param y - y position within the image of the pixel
00344       /// \param color - color to set pixel to
00345       ///
00346       /// \return CATResult result code.  CAT_SUCCESS on success.
00347       /// \sa GetPixel()
00348       CATResult SetPixel       (   CATInt32            x,
00349                                    CATInt32            y,
00350                                    const CATColor& color);
00351 
00352       /// Clear() sets all the pixels in the image to 0.
00353       ///
00354       /// \param transparent - if false, sets all alpha channels 
00355       ///                      to 255 (opaque). Otherwise, sets the
00356       ///                      alpha channels to 0 (transparent).      
00357       ///
00358       /// \return CATResult result code.
00359       CATResult Clear(bool transparent = true);
00360 
00361       /// FillRect() fills an area to a specific color.
00362       ///
00363       /// \param rect  - rectangle to fill
00364       /// \param color - color to fill to
00365       /// \return CATResult - CAT_SUCCESS on success.      
00366       CATResult FillRect(const CATRect& rect, const CATColor& color);
00367 
00368       /// SetSubPosition() moves the ROI of the image within its parent.
00369       /// Will return CAT_ERR_IMAGE_OPERATION_INVALID_ON_ROOT if you try
00370       /// to use this on a root image instead of a sub image.
00371       ///
00372       /// \param newXOffset - relative x offset of new pos within parent.
00373       /// \param newYOffset - relative y offset of new pos within parent.
00374       /// \param newWidth - new width of sub image.
00375       /// \param newHeight - new height of sub image.
00376       ///
00377       /// \return CATResult result code.      
00378       /// \sa CATImage::CreateSub()
00379       CATResult SetSubPosition (  CATInt32      newXOffset,
00380                                  CATInt32      newYOffset,
00381                                  CATInt32      newWidth,
00382                                  CATInt32      newHeight );
00383 
00384       /// GetRawDataPtr() retrieves the image data ptr.
00385       ///
00386       /// Remember that this may be a sub image, in which case the data ptr 
00387       /// returned is to the raw buffer of a parent image. 
00388       ///
00389       /// So, any time you access the raw data you should use the
00390       /// XOffsetAbs, YOffsetAbs, AbsWidth, and AbsHeight functions
00391       /// when calculating your pointers into the data.
00392       ///
00393       /// Also remember that if you modify a sub image, you'll be modifying
00394       /// the parent image and any other overlapping sub images.  If you
00395       /// want to muck with an image without messing up any others, use
00396       /// CATImage::CopyImage() first to get a base image that owns its own
00397       /// data.
00398       ///
00399       /// Note that the xOffset and yOffset are relative to parent. They will
00400       /// be calculated at runtime if you call this function.      
00401       ///
00402       /// \return unsigned char* to image data
00403       unsigned char* GetRawDataPtr() const;
00404       
00405       /// Returns relative offset within parent image.
00406       /// \return CATInt32 - X Offset relative to parent.
00407       CATInt32   XOffsetRel  () const;
00408 
00409       /// Returns relative offset within parent image.
00410       /// \return CATInt32 - Y Offset relative to parent.
00411       CATInt32   YOffsetRel  () const;
00412    
00413       /// Returns absolute X offset within fData.
00414       /// \return CATInt32 - Absolute x offset of current image within root
00415       CATInt32   XOffsetAbs  () const;
00416 
00417       /// Returns absolute Y offset within fData.
00418       /// \return CATInt32 - Absolute y offset of current image within root
00419       CATInt32   YOffsetAbs  () const;
00420 
00421       /// Returns the absolute width of the fData image buffer.
00422       /// \return CATInt32 - Absolute width of root image
00423       CATInt32   AbsWidth    () const;
00424 
00425       /// Returns the absolute height of the fData image buffer.
00426       /// \return CATInt32 - Absolute height of root image
00427       CATInt32   AbsHeight   () const;
00428 
00429       /// Returns width of image in pixels.
00430       /// \return CATInt32 - Width of image
00431       CATInt32   Width       () const;
00432 
00433       /// Returns height of image in pixels.
00434       /// \return CATInt32 - Height of image
00435       CATInt32   Height      () const;
00436 
00437       /// Returns size of image buffer in bytes.
00438       /// \return CATInt32 - Size of image in bytes
00439       CATInt32   Size        () const;
00440 
00441       /// Returns absolute size of parent image.
00442       /// \return CATInt32 - Absolute size of root image in bytes.
00443       CATInt32   AbsSize     () const;
00444 
00445       /// IsImageRoot() returns true if the image is a root (parent)
00446       /// image that owns its own data.  If the image is a sub image,
00447       /// it returns false.
00448       ///
00449       /// \return bool - true if the image is a root (without a parent),
00450       ///                or fase otherwise.
00451       bool  IsImageRoot () const;
00452 
00453       /// AddRef increments our reference count and calls
00454       /// AddRef on our parent if one exists.
00455       /// \return long - current reference count
00456       unsigned long  AddRef();
00457 
00458       /// DecRef decrements our reference count and calls
00459       /// ReleaseImage() on our parent if one exists. 
00460       /// \return long - current reference count
00461       unsigned long  DecRef();      
00462       
00463       /// GetRefCount() retrieves the current reference
00464       /// count
00465       /// return unsigned long - current reference count
00466       /// \sa AddRef(), DecRef()
00467       unsigned long GetRefCount();
00468 
00469       // Debugging func for saving image to disk as a .png
00470       CATResult DbgSave     (  const CATWChar*  filename );
00471 
00472    protected:
00473       /// Constructor for CATImage - use CATImage::CreateImage() or similar 
00474       /// static functions instead!
00475       ///
00476       CATImage  ();
00477       
00478       /// Destructor for CATImage - use CATImage::ReleaseImage()
00479       virtual ~CATImage();
00480 
00481       /// operator= is overridden to generate an error if someone
00482       /// attempts to use it - Don't use it!
00483       /// Use CreateCopy() or CreateSub() instead depending on whether you
00484       /// want a deep or shallow copy of the object.            
00485       CATImage& operator=(const CATImage& img);
00486 
00487       /// Create - internal image creation function.
00488       /// Creates the buffer and sets it up, then calls AddRef().
00489       ///
00490       /// \param width - width of image in pixels.
00491       /// \param height - height of image in pixels.
00492       /// \param init - if true, initializes image pixels to 0.
00493       /// \param transparent - if false, sets all alpha channels 
00494       ///                      to 255 (opaque). Otherwise, sets the
00495       ///                      alpha channels to 0 (transparent).      
00496       ///                      Ignored if init == false.
00497       ///
00498       /// \return CATResult result code.
00499       /// \sa ::CATResult_CORE_ENUM, ::CATResult_IMAGE_ENUM
00500       CATResult    Create   (  CATInt32            width, 
00501                               CATInt32            height, 
00502                               bool           init,
00503                               bool           transparent);
00504 
00505       //---------------------------------------------------------------------
00506       // PNG callbacks
00507 
00508       /// PNGRead() reads from the current stream into the buffer
00509       /// provided by libpng.
00510       ///
00511       /// You shouldn't need to call this directly - these are called
00512       /// by libpng only.
00513       ///
00514       /// \param png_ptr - structure for the .png library. The CATStream*
00515       ///                  for the current stream is in png_ptr->io_ptr.
00516       /// \param data    - target buffer
00517       /// \param length  - number of bytes to read.
00518       /// \return none. Throws a CATRESULT on error.
00519       /// \sa Load()
00520       static void PNGRead(    png_structp       png_ptr,
00521                               png_bytep         data, 
00522                               png_size_t        length);
00523 
00524 
00525       /// PNGWrite() writes to the current stream from the buffer
00526       /// provided by libpng.
00527       ///
00528       /// You shouldn't need to call this directly - these are called
00529       /// by libpng only.
00530       ///
00531       /// \param png_ptr - structure for the .png library. The CATStream*
00532       ///                  for the current stream is in png_ptr->io_ptr.
00533       /// \param data    - source buffer
00534       /// \param length  - number of bytes to write.
00535       /// \return none. Throws a CATRESULT on error.
00536       /// \sa Save()
00537       static void PNGWrite(   png_structp       png_ptr,
00538                               png_bytep         data, 
00539                               png_size_t        length);
00540 
00541 
00542       /// PNGFlush() flushes the current stream for libpng.
00543       ///
00544       /// You shouldn't need to call this directly - these are called
00545       /// by libpng only.
00546       ///
00547       /// \param png_ptr - structure for the .png library. The CATStream*
00548       ///                  for the current stream is in png_ptr->io_ptr.
00549       /// \return none. Throws a CATRESULT on error.
00550       /// \sa Load(), Save()
00551       static void PNGFlush(   png_structp       png_ptr);
00552       
00553       /// PNGError() is called by libpng when a fatal error occurs.
00554       ///
00555       /// This just throws a CATResult when called.
00556       ///
00557       /// \param png_ptr - structure for .png lib.
00558       /// \param error_msg - ASCIIZ message reporting the error.
00559       static void PNGError(   png_structp       png_ptr,
00560                               png_const_charp   error_msg);
00561 
00562       /// PNGWarning() is called by libpng when a recoverable error occurs.
00563       ///
00564       /// This just throws a CATResult when called.
00565       ///
00566       /// \param png_ptr - structure for .png lib.
00567       /// \param warning_msg - ASCIIZ message reporting the warning.
00568       static void PNGWarning( png_structp       png_ptr,
00569                               png_const_charp   warning_msg);
00570 
00571 
00572 
00573 
00574    //---------------------------------------------------------------------
00575    private:
00576       
00577       // Basic image information
00578       CATInt32         fWidth;          ///< Width in pixels.      
00579       
00580       CATInt32         fHeight;         ///< Height in pixels.      
00581       
00582       CATUInt8*        fData;           ///< Image data.
00583                                         ///< This may be a pointer to the parent
00584                                         ///< image's buffer. Remember to use
00585                                         ///< offsets. 
00586       // SubImage/ROI information
00587       CATInt32         fXOffset;        ///< X Offset within parent image.
00588                                         ///< To find offset within fData, 
00589                                         ///< call XOffsetAbs().      
00590 
00591       CATInt32         fYOffset;        ///< Y Offset within parent image.
00592                                         ///< To find offset within fData,
00593                                         ///< call YOffsetAbs().      
00594 
00595       bool             fOwnData;        ///< Set to true if we own image data.
00596                                         ///< (i.e. are we the parent?)      
00597    
00598       CATUInt32        fRefCount;       ///< Ref count - inc for each sub image.      
00599 
00600       CATImage*        fParentImage;    ///< Parent image - so we can decrement
00601                                         ///<       ref count on destruction.      
00602 };
00603 
00604 #endif // _CATImage_H_

Generated on Mon Feb 11 04:09:44 2008 for Game Accessibility Suite by doxygen 1.5.4