ImageFormat_PNG.cpp
Go to the documentation of this file.00001 //*** ImageFormat_PNG.cpp *** 00002 00003 #include "ImageFormat_PNG.h" 00004 #include "Debug.h" 00005 #include "Asset.h" 00006 #include "StandardLibrary.h" 00007 00008 #define WIN32_LEAN_AND_MEAN 00009 #define VC_EXTRALEAN 00010 #include "libpng/png.h" 00011 00012 //*** Register *** 00013 00014 void ImageFormat_PNG::Register() 00015 { 00016 ImageFormat::RegisterImageFormat(TestAsset,Create); 00017 } 00018 00019 00020 //*** Create *** 00021 00022 ImageFormat* ImageFormat_PNG::Create(const Asset& asset) 00023 { 00024 return new ImageFormat_PNG(asset); 00025 } 00026 00027 00028 //*** TestAsset *** 00029 00030 bool ImageFormat_PNG::TestAsset(const Asset& asset) 00031 { 00032 // Check if the header matches PNG files 00033 if (asset.Open()) 00034 { 00035 unsigned char pngheader[]={137,80,78,71,13,10,26,10}; 00036 unsigned char buffer[8]; 00037 asset.Read(buffer,8); 00038 asset.Close(); 00039 if (MemCmp(buffer,pngheader,8)==0) 00040 { 00041 return true; 00042 } 00043 } 00044 00045 return false; 00046 } 00047 00048 00049 //*** png_user_read_fn *** 00050 00051 void png_user_read_fn(png_structp assetptr, png_bytep buffer, png_size_t size) 00052 { 00053 Asset* asset=static_cast<Asset*>(assetptr->io_ptr); 00054 asset->Read(buffer,size); 00055 } 00056 00057 00058 //*** Constructor *** 00059 00060 ImageFormat_PNG::ImageFormat_PNG(const Asset& asset): 00061 png_ptr_(0), 00062 info_ptr_(0) 00063 { 00064 if (asset.Open()) 00065 { 00066 00067 png_ptr_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); 00068 Assert(png_ptr_,"Couldn't create png read struct"); 00069 if (!png_ptr_) 00070 { 00071 return; 00072 } 00073 00074 info_ptr_ = png_create_info_struct((png_structp)png_ptr_); 00075 Assert(info_ptr_,"Couldn't create png info struct"); 00076 if (!info_ptr_) 00077 { 00078 png_destroy_read_struct((png_structpp)&png_ptr_, 0,0); 00079 return; 00080 } 00081 00082 png_set_read_fn(static_cast<png_structp>(png_ptr_), const_cast<Asset*>(&asset), png_user_read_fn); 00083 00084 png_read_png(static_cast<png_structp>(png_ptr_), static_cast<png_infop>(info_ptr_), /*PNG_TRANSFORM_STRIP_16|*/PNG_TRANSFORM_EXPAND|PNG_TRANSFORM_BGR, 0); 00085 00086 asset.Close(); 00087 } 00088 00089 } 00090 00091 00092 //*** Destructor *** 00093 00094 ImageFormat_PNG::~ImageFormat_PNG() 00095 { 00096 png_destroy_read_struct(reinterpret_cast<png_structpp>(&png_ptr_), reinterpret_cast<png_infopp>(&info_ptr_),0); 00097 } 00098 00099 00100 //*** GetWidth *** 00101 00102 int ImageFormat_PNG::GetWidth() 00103 { 00104 if (info_ptr_) 00105 { 00106 return static_cast<png_infop>(info_ptr_)->width; 00107 } 00108 00109 return 0; 00110 } 00111 00112 00113 //*** GetHeight *** 00114 00115 int ImageFormat_PNG::GetHeight() 00116 { 00117 if (info_ptr_) 00118 { 00119 return static_cast<png_infop>(info_ptr_)->height; 00120 } 00121 00122 return 0; 00123 } 00124 00125 00126 //*** GetCelCount *** 00127 00128 int ImageFormat_PNG::GetCelCount() 00129 { 00130 return 1; 00131 } 00132 00133 00134 //*** GetCelDelay *** 00135 00136 float ImageFormat_PNG::GetCelDelay(int celIndex) 00137 { 00138 return 0; 00139 } 00140 00141 00142 //*** CopyPixels *** 00143 00144 void ImageFormat_PNG::CopyPixels(unsigned int* destination) 00145 { 00146 if (!info_ptr_ || !png_ptr_) 00147 { 00148 return; 00149 } 00150 00151 png_infop info_ptr=static_cast<png_infop>(info_ptr_); 00152 png_structp png_ptr=static_cast<png_structp>(png_ptr_); 00153 00154 Assert(info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA || info_ptr->color_type==PNG_COLOR_TYPE_RGB,"Unknown PNG format"); 00155 if (info_ptr->color_type!=PNG_COLOR_TYPE_RGB_ALPHA && info_ptr->color_type!=PNG_COLOR_TYPE_RGB) 00156 { 00157 return; 00158 } 00159 00160 if (info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA) 00161 { 00162 unsigned char* data=reinterpret_cast<unsigned char*>(destination); 00163 png_byte** row_pointers=png_get_rows(png_ptr, info_ptr); 00164 int rowSize=info_ptr->width*4; 00165 00166 for (unsigned int y=0; y<info_ptr->height; y++) 00167 { 00168 for (unsigned int x=0; x<info_ptr->width; x++) 00169 { 00170 data[x*4+y*rowSize+0]=row_pointers[y][x*4+0]; 00171 data[x*4+y*rowSize+1]=row_pointers[y][x*4+1]; 00172 data[x*4+y*rowSize+2]=row_pointers[y][x*4+2]; 00173 data[x*4+y*rowSize+3]=row_pointers[y][x*4+3]; 00174 } 00175 } 00176 } 00177 else 00178 { 00179 unsigned char* data=reinterpret_cast<unsigned char*>(destination); 00180 png_byte** row_pointers=png_get_rows(png_ptr, info_ptr); 00181 int rowSize=info_ptr->width*4; 00182 00183 for (unsigned int y=0; y<info_ptr->height; y++) 00184 { 00185 for (unsigned int x=0; x<info_ptr->width; x++) 00186 { 00187 data[x*4+y*rowSize+0]=row_pointers[y][x*3+0]; 00188 data[x*4+y*rowSize+1]=row_pointers[y][x*3+1]; 00189 data[x*4+y*rowSize+2]=row_pointers[y][x*3+2]; 00190 data[x*4+y*rowSize+3]=0xff; 00191 } 00192 } 00193 } 00194 } 00195 00196 00197 //*** Save *** 00198 00199 void ImageFormat_PNG::Save(const Filename& filename, int width, int height, void* data) 00200 { 00201 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
