Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Corona.cpp

Go to the documentation of this file.
00001 #include <memory>
00002 #include <string>
00003 #include <vector>
00004 #include <string.h>
00005 #include <ctype.h>
00006 #include "corona.h"
00007 #include "MemoryFile.h"
00008 #include "Open.h"
00009 #include "Save.h"
00010 #include "SimpleImage.h"
00011 
00012 
00013 namespace corona {
00014   namespace hidden {
00015 
00017 
00018     COR_EXPORT(const char*) CorGetVersion() {
00019       return "1.0.2";
00020     }
00021 
00023 
00024     class FFDImpl : public FileFormatDesc {
00025     public:
00026       FFDImpl(FileFormat format, const char* description, const char* exts) {
00027         m_format = format;
00028         m_description = description;
00029 
00030         const char* ext = exts;
00031         while (*ext) {
00032           m_extensions.push_back(ext);
00033           ext += strlen(ext) + 1;
00034         }
00035       }
00036 
00037       FileFormat getFormat()             { return m_format;                }
00038       const char* getDescription()       { return m_description.c_str();   }
00039       size_t getExtensionCount()         { return m_extensions.size();     }
00040       const char* getExtension(size_t i) { return m_extensions[i].c_str(); }
00041 
00042     private:
00043       FileFormat m_format;
00044       std::string m_description;
00045       std::vector<std::string> m_extensions;
00046     };
00047 
00048     FFDImpl ffPNG (FF_PNG,  "PNG Files",  "png\0");
00049     FFDImpl ffJPEG(FF_JPEG, "JPEG Files", "jpeg\0jpg\0");
00050     FFDImpl ffPCX (FF_PCX,  "PCX Files",  "pcx\0");
00051     FFDImpl ffBMP (FF_BMP,  "BMP Files",  "bmp\0");
00052     FFDImpl ffTGA (FF_TGA,  "TGA Files",  "tga\0");
00053     FFDImpl ffGIF (FF_GIF,  "GIF Files",  "gif\0");
00054 
00055     const int MAX_FORMAT_COUNT = 64;
00056     FileFormatDesc** g_read_formats  = 0;
00057     FileFormatDesc** g_write_formats = 0;
00058     FileFormatDesc* g_read_array[MAX_FORMAT_COUNT + 1]  = {0};
00059     FileFormatDesc* g_write_array[MAX_FORMAT_COUNT + 1] = {0};
00060 
00061 
00062     COR_EXPORT(FileFormatDesc**) CorGetSupportedReadFormats() {
00063       if (!g_read_formats) {
00064         g_read_formats = g_read_array;
00065         FileFormatDesc** f = g_read_formats;
00066 #ifndef NO_PNG
00067         *f++ = &ffPNG;
00068 #endif
00069 #ifndef NO_JPEG
00070         *f++ = &ffJPEG;
00071 #endif
00072         *f++ = &ffPCX;
00073         *f++ = &ffBMP;
00074         *f++ = &ffTGA;
00075         *f++ = &ffGIF;
00076       }
00077       return g_read_formats;
00078     }
00079 
00080 
00081     COR_EXPORT(FileFormatDesc**) CorGetSupportedWriteFormats() {
00082       if (!g_write_formats) {
00083         g_write_formats = g_write_array;
00084         FileFormatDesc** f = g_write_formats;
00085 #ifndef NO_PNG
00086         *f++ = &ffPNG;
00087 #endif
00088         *f++ = &ffTGA;
00089       }
00090       return g_write_formats;
00091     }
00092 
00094 
00095     COR_EXPORT(Image*) CorCreateImage(
00096       int width,
00097       int height,
00098       PixelFormat format)
00099     {
00100       return CreateImage(width, height, format, 0);
00101     }
00102 
00104 
00105     COR_EXPORT(Image*) CorCreateImageWithPixels(
00106       int width,
00107       int height,
00108       PixelFormat format,
00109       void* pixels)
00110     {
00111       // this function only supports creation of non-palettized images
00112       if (!IsDirect(format)) {
00113         return 0;
00114       }
00115 
00116       int size = width * height * GetPixelSize(format);
00117       byte* p = new byte[size];
00118       if (pixels) {
00119         memcpy(p, pixels, size);
00120       } else {
00121         memset(p, 0, size);
00122       }
00123       return new SimpleImage(width, height, format, p);
00124     }
00125 
00127 
00128     COR_EXPORT(Image*) CorCreatePalettizedImage(
00129       int width,
00130       int height,
00131       PixelFormat format,
00132       int palette_size,
00133       PixelFormat palette_format)
00134     {
00135       // only support creation of palettized images
00136       if (!IsPalettized(format) || !IsDirect(palette_format)) {
00137         return 0;
00138       }
00139 
00140       // make sure the palette is the right size
00141       if (palette_size != GetPaletteSize(format)) {
00142         return 0;
00143       }
00144 
00145       int size = width * height * GetPixelSize(format);
00146       byte* pixels = new byte[size];
00147       memset(pixels, 0, size);
00148 
00149       int palette_bytes = palette_size * GetPixelSize(palette_format);
00150       byte* palette = new byte[palette_bytes];
00151       memset(palette, 0, palette_bytes);
00152 
00153       return new SimpleImage(width, height, format, pixels,
00154                              palette, palette_size, palette_format);      
00155     }
00156 
00158 
00159     COR_EXPORT(Image*) CorCloneImage(
00160       Image* source,
00161       PixelFormat format)
00162     {
00163       if (!source) {
00164         // we need an image to clone :)
00165         return 0;
00166       }
00167 
00168       const int width = source->getWidth();
00169       const int height = source->getHeight();
00170       const PixelFormat source_format = source->getFormat();
00171 
00172       const int source_pixel_size = GetPixelSize(source_format);
00173       if (source_pixel_size == 0) {
00174         // unknown pixel size?
00175         return 0;
00176       }
00177 
00178       // duplicate the image
00179       int image_size = width * height * source_pixel_size;
00180       byte* pixels = new byte[image_size];
00181       memcpy(pixels, source->getPixels(), image_size);
00182       
00183       if (IsPalettized(source_format)) {
00184         // clone palette
00185         int palette_size = source->getPaletteSize();
00186         PixelFormat palette_format = source->getPaletteFormat();
00187         int palette_bytes = palette_size * GetPixelSize(palette_format);
00188         byte* palette = new byte[palette_bytes];
00189         memcpy(palette, source->getPalette(), palette_bytes);
00190         Image* image = new SimpleImage(width, height, source_format, pixels,
00191                                        palette, palette_size, palette_format);
00192         return ConvertImage(image, format);
00193       }
00194 
00195       Image* image = new SimpleImage(width, height, source_format, pixels);
00196       return ConvertImage(image, format);
00197     }
00198 
00200 
00201     COR_EXPORT(Image*) CorOpenImage(
00202       const char* filename,
00203       FileFormat file_format)
00204     {
00205       if (!filename) {
00206         return 0;
00207       }
00208 
00209       std::auto_ptr<File> file(OpenFile(filename, false));
00210       return CorOpenImageFromFile(file.get(), file_format);
00211     }
00212 
00214 
00215     COR_EXPORT(Image*) CorOpenImageFromFile(
00216       File* file,
00217       FileFormat file_format)
00218     {
00219       if (!file) {
00220         return 0;
00221       }
00222 
00223 #define TRY_TYPE(type)                                 \
00224   {                                                    \
00225     Image* image = CorOpenImageFromFile(file, (type)); \
00226     if (image) { return image; }                       \
00227   }
00228 
00229       file->seek(0, File::BEGIN);
00230       switch (file_format) {
00231         case FF_AUTODETECT: {
00232 #ifndef NO_PNG
00233           TRY_TYPE(FF_PNG);
00234 #endif
00235 #ifndef NO_JPEG
00236           TRY_TYPE(FF_JPEG);
00237 #endif
00238           TRY_TYPE(FF_PCX);
00239           TRY_TYPE(FF_BMP);
00240           TRY_TYPE(FF_TGA);
00241           TRY_TYPE(FF_GIF);
00242           return 0;
00243         }
00244         
00245 #ifndef NO_PNG
00246         case FF_PNG:  return OpenPNG(file);
00247 #endif
00248 #ifndef NO_JPEG
00249         case FF_JPEG: return OpenJPEG(file);
00250 #endif
00251         case FF_PCX:  return OpenPCX(file);
00252         case FF_BMP:  return OpenBMP(file);
00253         case FF_TGA:  return OpenTGA(file);
00254         case FF_GIF:  return OpenGIF(file);
00255         default:      return 0;
00256       }
00257     }
00258 
00260 
00261     int strcmp_ci(const char* a, const char* b) {
00262       while (*a && *b) {
00263         const int diff = tolower(*a) - tolower(*b);
00264         if (diff != 0) {
00265           return diff;
00266         }
00267         ++a;
00268         ++b;
00269       }
00270       return tolower(*a) - tolower(*b);
00271     }
00272 
00273     bool ends_with(const char* str, const char* ext) {
00274       const int str_len = strlen(str);
00275       const int ext_len = strlen(ext);
00276       return (str_len >= ext_len &&
00277               strcmp_ci(str + str_len - ext_len, ext) == 0);
00278     }
00279 
00280     COR_EXPORT(bool) CorSaveImage(
00281       const char* filename,
00282       FileFormat file_format,
00283       Image* image)
00284     {
00285       if (!filename) {
00286         return false;
00287       }
00288 
00289       if (file_format == FF_AUTODETECT) {
00290         if (ends_with(filename, ".png")) {
00291           file_format = FF_PNG;
00292         } else if (ends_with(filename, ".tga")) {
00293           file_format = FF_TGA;
00294         } else {
00295           return false;
00296         }
00297       }
00298 
00299       std::auto_ptr<File> file(OpenFile(filename, true));
00300       return CorSaveImageToFile(file.get(), file_format, image);
00301     }
00302 
00304 
00305     COR_EXPORT(bool) CorSaveImageToFile(
00306       File* file,
00307       FileFormat file_format,
00308       Image* image)
00309     {
00310       if (!file || !image) {
00311         return false;
00312       }
00313 
00314       switch (file_format) {
00315 #ifndef NO_PNG
00316         case FF_PNG:  return SavePNG(file, image);
00317 #endif
00318         case FF_JPEG: return false;
00319         case FF_PCX:  return false;
00320         case FF_BMP:  return false;
00321         case FF_TGA:  return SaveTGA(file, image);
00322         case FF_GIF:  return false;
00323         default:      return false;
00324       }
00325     }
00326 
00328 
00329     COR_EXPORT(int) CorGetPixelSize(PixelFormat format) {
00330       switch (format) {
00331         case PF_R8G8B8A8: return 4;
00332         case PF_R8G8B8:   return 3;
00333         case PF_B8G8R8A8: return 4;
00334         case PF_B8G8R8:   return 3;
00335         case PF_I8:       return 1;
00336         default:          return 0;
00337       }
00338     }
00339 
00341 
00342   }
00343 }

Generated on Thu Oct 2 12:59:30 2003 for corona by doxygen1.3-rc1