Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

pixeldata.h

Go to the documentation of this file.
00001 /*
00002         The new pixelformat converters in ClanLib.
00003 */
00004 
00005 #ifndef header_pixeldata
00006 #define header_pixeldata
00007 
00008 #include <iostream>
00009 
00010 extern "C"
00011 {
00012         #include <Hermes/H_Conv.h>
00013         #include <Hermes/H_Pal.h>
00014 }
00015 
00016 #include "surfaceprovider_32bpp.h"
00017 
00018 // #define HERMES_ALIGN_BUG 2
00019 
00020 class CL_PixelData
00021 {
00022 protected:
00023         HermesHandle m_handle;
00024 
00025         HermesFormat *m_src_format;
00026         HermesHandle m_src_palette;
00027 
00028         HermesFormat *m_dest_format;
00029         
00030         CL_SurfaceProvider *m_provider;
00031         bool m_delete_provider;
00032 
00033         unsigned char *scanline;
00034 
00035 public:
00036         CL_PixelData(
00037                 unsigned int red_mask,
00038                 unsigned int green_mask,
00039                 unsigned int blue_mask,
00040                 unsigned int alpha_mask,
00041                 CL_SurfaceProvider *src,
00042                 unsigned int bytes_per_pixel)
00043         {
00044                 m_delete_provider = false;
00045 
00046                 m_provider = src;
00047         
00048                 // Access surface provider until we're destructed.
00049                 m_provider->lock();
00050                 
00051                 // if PAL8, convert to RGBA8888 because Hermes doesn't support
00052                 // colorkeys.
00053                 if (src->get_depth() == 8)
00054                 {
00055                         m_provider = new CL_SurfaceProvider_32bpp(src);
00056                         m_provider->lock();
00057                         if (m_delete_provider) delete src;
00058                         m_delete_provider = true;
00059                 }
00060 
00061                 m_handle = Hermes_ConverterInstance(HERMES_CONVERT_NORMAL);
00062                 cl_assert(m_handle!=0);
00063 
00064                 m_src_palette = Hermes_PaletteInstance();
00065                 cl_assert(m_src_palette != 0);
00066 
00067                 // Set dest pixel format:
00068                 
00069                 m_dest_format = Hermes_FormatNew(
00070                         bytes_per_pixel*8,
00071                         red_mask,
00072                         green_mask,
00073                         blue_mask,
00074                         alpha_mask,
00075                         0 /* indexed */);
00076                 cl_assert(m_dest_format != 0);
00077 
00078                 // only PAL8 colorkey support (for now):
00079                 // dv: 05.12 23:53 removed below
00080                 //cl_assert(m_provider->uses_src_colorkey() == false);
00081 
00082                 // Set source pixel format:
00083 
00084                 m_src_format = Hermes_FormatNew(
00085                         m_provider->get_depth(),
00086                         m_provider->get_red_mask(),
00087                         m_provider->get_green_mask(),
00088                         m_provider->get_blue_mask(),
00089                         m_provider->get_alpha_mask(),
00090                         0 /* indexed */);
00091                 cl_assert(m_src_format != 0);
00092 
00093                 scanline = new unsigned char[get_bytes_per_pixel()*(get_width()/*+HERMES_ALIGN_BUG*/)];
00094         }
00095 
00096         virtual ~CL_PixelData()
00097         {
00098                 Hermes_ConverterReturn(m_handle);
00099                 Hermes_PaletteReturn(m_src_palette);
00100 
00101                 Hermes_FormatFree(m_src_format);
00102                 Hermes_FormatFree(m_dest_format);
00103 
00104                 delete[] scanline;
00105 
00106                 // Release surface provider.
00107                 m_provider->unlock();
00108                 if (m_delete_provider) delete m_provider;
00109         }
00110 
00111         unsigned int get_width()
00112         {
00113                 return m_provider->get_width();
00114         }
00115 
00116         unsigned int get_height()
00117         {
00118                 return m_provider->get_height();
00119         }
00120         
00121         unsigned int get_bytes_per_pixel()
00122         {
00123                 return (m_dest_format->bits+7)/8;
00124         }
00125 
00126         int get_bytes_pr_line() { return get_bytes_per_pixel()*get_width(); }
00127         
00128         void get_line_pixel_to_dest(int y, unsigned char *dest)
00129         {
00130                 // Hack to support alpha when Hermes doesn't:
00131 
00132                 if ((unsigned int) y >= m_provider->get_height()*m_provider->get_num_frames())
00133                 {
00134                         std::cout<< "Tried to obtain line " << y << std::endl;
00135                         cl_assert(false);
00136                 }
00137 
00138                 int width = get_width();
00139 
00140                 if (m_dest_format->a == 255 && get_bytes_per_pixel()==1)
00141                 {
00142                         if (m_src_format->a == 0)
00143                         {
00144                                 memset(dest, 255, width);
00145                                 return;
00146                         }
00147                         switch (m_src_format->bits)
00148                         {
00149                         case 15:
00150                         case 16:
00151                                 {
00152                                         unsigned short *ptr =
00153                                                 (unsigned short *) m_provider->get_data();
00154 
00155                                         for (int x=0; x<width; x++)
00156                                         {
00157                                                 dest[x] = (unsigned char) (ptr[x+y*width]&255);
00158                                         }
00159                                 }
00160                                 return;
00161 
00162                         case 32:
00163                                 {
00164                                         unsigned int *ptr =
00165                                                 (unsigned int *) m_provider->get_data();
00166 
00167                                         for (int x=0; x<width; x++)
00168                                         {
00169                                                 dest[x] = (unsigned char) (ptr[x+y*width]&255);
00170                                         }
00171                                 }
00172                                 return;
00173                         }
00174                 }
00175         
00176         
00177                 int res = Hermes_ConverterRequest(
00178                         m_handle,
00179                         m_src_format,
00180                         m_dest_format);
00181 
00182                 if (res == 0)
00183                 {
00184                         std::cout <<"Hermes ConverterRequest FAILED:" << std::endl;
00185                         dump_assert_info(y);
00186                         cl_assert(res != 0);
00187                 }
00188 
00189                 res = Hermes_ConverterPalette(m_handle, m_src_palette, 0);
00190                 if (res == 0)
00191                 {
00192                         std::cout <<"Hermes ConverterPalette FAILED:" << std::endl;
00193                         dump_assert_info(y);
00194                         cl_assert(res != 0);
00195                 }
00196 
00197 /*              if (width % HERMES_ALIGN_BUG != 0) // Hermes bug - workaround.
00198                 {
00199                         int new_width = width+HERMES_ALIGN_BUG-width%HERMES_ALIGN_BUG;
00200 //                      std::cout <<"width: " << width << " -> new_width: " << new_width <<std::endl;
00201 
00202                         int size_buffer = m_provider->get_pitch()+HERMES_ALIGN_BUG*4;
00203                         void *bug_buffer = new char[size_buffer];
00204                         memcpy(
00205                                 bug_buffer,
00206                                 ((unsigned char *) m_provider->get_data())+m_provider->get_pitch()*y,
00207                                 m_provider->get_pitch());
00208 
00209                         res = Hermes_ConverterCopy(
00210                                 m_handle,
00211                                 bug_buffer,
00212                                 0,
00213                                 0,
00214                                 new_width,
00215                                 1, // m_provider->get_height(),
00216                                 size_buffer,
00217                                 dest,
00218                                 0,
00219                                 0,
00220                                 new_width,
00221                                 1, // m_provider->get_height(),
00222                                 get_bytes_per_pixel()*new_width
00223                                 );
00224 
00225                         res = 1;
00226                         delete[] bug_buffer;
00227                 }
00228                 else*/
00229                 {
00230                         res = Hermes_ConverterCopy(
00231                                 m_handle,
00232                                 ((unsigned char *) m_provider->get_data())+m_provider->get_pitch()*y,
00233                                 0,
00234                                 0,
00235                                 width,
00236                                 1, // m_provider->get_height(),
00237                                 m_provider->get_pitch(),
00238                                 dest,
00239                                 0,
00240                                 0,
00241                                 width,
00242                                 1, // m_provider->get_height(),
00243                                 get_bytes_per_pixel()*width
00244                                 );
00245                 }
00246                         
00247                 if (res == 0)
00248                 {
00249                         std::cout <<"Hermes ConverterCopy FAILED:" << std::endl;
00250                         dump_assert_info(y);
00251                         cl_assert(res != 0);
00252                 }
00253         }
00254         
00255         void dump_assert_info(int line)
00256         {
00257                 std::cout <<"  m_src_format->r = " << (unsigned int) m_src_format->r <<std::endl;
00258                 std::cout <<"  m_src_format->g = " << (unsigned int) m_src_format->g <<std::endl;
00259                 std::cout <<"  m_src_format->b = " << (unsigned int) m_src_format->b <<std::endl;
00260                 std::cout <<"  m_src_format->a = " << (unsigned int) m_src_format->a <<std::endl;
00261                 std::cout <<"  m_src_format->bits = " << (unsigned int) m_src_format->bits <<std::endl;
00262                 std::cout <<"  m_src_format->indexed = " << (unsigned int) m_src_format->indexed <<std::endl <<std::endl;
00263 
00264                 std::cout <<"  m_dest_format->r = " << (unsigned int) m_dest_format->r <<std::endl;
00265                 std::cout <<"  m_dest_format->g = " << (unsigned int) m_dest_format->g <<std::endl;
00266                 std::cout <<"  m_dest_format->b = " << (unsigned int) m_dest_format->b <<std::endl;
00267                 std::cout <<"  m_dest_format->a = " << (unsigned int) m_dest_format->a <<std::endl;
00268                 std::cout <<"  m_dest_format->bits = " << (unsigned int) m_dest_format->bits <<std::endl;
00269                 std::cout <<"  m_dest_format->indexed = " << (unsigned int) m_dest_format->indexed <<std::endl <<std::endl;
00270                 
00271                 std::cout <<"  line: " << line <<std::endl <<std::endl;
00272 
00273                 std::cout <<"  source pitch: " << m_provider->get_pitch() <<std::endl;
00274                 std::cout <<"  source width: " << m_provider->get_width() <<std::endl;
00275                 std::cout <<"  source height: " << 1 <<std::endl <<std::endl;
00276 
00277                 std::cout <<"  dest pitch: " << m_provider->get_width() * get_bytes_per_pixel() <<std::endl;
00278                 std::cout <<"  dest width: " << get_width() <<std::endl;
00279                 std::cout <<"  dest height: " << 1 <<std::endl <<std::endl;
00280 
00281                 std::cout <<"  provider height: " << m_provider->get_height() <<std::endl;
00282                 std::cout <<"  provider num frames: " << m_provider->get_num_frames() <<std::endl <<std::endl;
00283         }
00284 
00285         unsigned char *get_line_pixel(int y)
00286         {
00287                 get_line_pixel_to_dest(y, scanline);
00288                 return scanline;
00289         }
00290         
00291         unsigned short *get_line_pixel16(int y)
00292         {
00293                 return (unsigned short *) get_line_pixel(y);
00294         }
00295         
00296         unsigned int *get_line_pixel32(int y)
00297         {
00298                 return (unsigned int *) get_line_pixel(y);
00299         }
00300 };
00301 
00302 class CL_PixelData_Palette
00303 {
00304 public:
00305         CL_PixelData_Palette(
00306                 CL_Palette * /*dest_pal*/,
00307                 CL_SurfaceProvider * /*src*/)
00308         {
00309                 cl_assert(false); // not implemented yet.
00310         }
00311         
00312         virtual ~CL_PixelData_Palette()
00313         {
00314         }
00315         
00316         unsigned int get_width()
00317         {
00318                 return 0;
00319         }
00320 
00321         unsigned int get_height()
00322         {
00323                 return 0;
00324         }
00325         
00326         bool has_colorkey()
00327         {
00328                 return false;
00329         }
00330 
00331         unsigned int get_colorkey()
00332         {
00333                 return 0;
00334         }
00335         
00336         unsigned char *get_line_pixel(int /*y*/)
00337         {
00338                 return NULL;
00339         }
00340 };
00341 
00342 #endif

Generated at Wed Apr 4 19:54:02 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001