enigma-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Enigma-cvs] enigma/src menus_internal.hh,1.3,1.4


From: Ralf Westram <address@hidden>
Subject: [Enigma-cvs] enigma/src menus_internal.hh,1.3,1.4
Date: Thu, 30 Oct 2003 19:12:15 +0000

Update of /cvsroot/enigma/enigma/src
In directory subversions:/tmp/cvs-serv18931/src

Modified Files:
        menus_internal.hh 
Log Message:
- LevelPreviewCache saves generated previews and loads them if present
- added savePNG
- deletes outdated previews



Index: menus_internal.hh
===================================================================
RCS file: /cvsroot/enigma/enigma/src/menus_internal.hh,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** menus_internal.hh   20 Oct 2003 08:05:46 -0000      1.3
--- menus_internal.hh   30 Oct 2003 19:12:13 -0000      1.4
***************
*** 19,22 ****
--- 19,25 ----
   */
  
+ #include <png.h>
+ #include <iostream>
+ 
  //----------------------------------------------------------------------
  // Helper classes
***************
*** 49,53 ****
          int               m_maxheight;
      public:
!         VTableBuilder (Menu *menu, const px::Rect &widgetsize, 
                         int vspacing, int hspacing, int max_height)
          : m_menu(menu), m_widgetsize(widgetsize)
--- 52,56 ----
          int               m_maxheight;
      public:
!         VTableBuilder (Menu *menu, const px::Rect &widgetsize,
                         int vspacing, int hspacing, int max_height)
          : m_menu(menu), m_widgetsize(widgetsize)
***************
*** 57,61 ****
              m_maxheight = max_height;
          }
!         
          Widget *add (Widget *w) {
              m_widgets.push_back(w);
--- 60,64 ----
              m_maxheight = max_height;
          }
! 
          Widget *add (Widget *w) {
              m_widgets.push_back(w);
***************
*** 69,73 ****
              int nrows = (m_widgets.size() + ncolumns - 1) / ncolumns;
              int i=0;
!             int x=0; 
              for (int col = 0; col < ncolumns; col++) {
                  int y=0;
--- 72,76 ----
              int nrows = (m_widgets.size() + ncolumns - 1) / ncolumns;
              int i=0;
!             int x=0;
              for (int col = 0; col < ncolumns; col++) {
                  int y=0;
***************
*** 126,158 ****
  
  
      class LevelPreviewCacheElem {
!         Surface *surface;
!         unsigned idx;
  
          LevelPreviewCacheElem(const LevelPreviewCacheElem&);
          LevelPreviewCacheElem& operator = (const LevelPreviewCacheElem& 
other);
      public:
!         LevelPreviewCacheElem(LevelPack *lp, unsigned idx_, int xsize, int 
ysize)
!         : surface(0) , idx(idx_)
          {
!             surface = LevelPreview(lp, idx); // do not free, points to 
BackBuffer
!             if (surface) {
!                 const Rect&  game_area    = display::GetGameArea();
!                 Surface     *game_surface = Grab(surface, game_area);
  
-                 if (game_surface) {
-                     surface = game_surface->zoom(xsize, ysize);
                      delete game_surface;
                  }
-                 else {
-                     surface = 0; // avoid delete
-                 }
              }
- 
-             // fprintf(stderr, "Created preview for #%i. surface=%p\n", idx, 
surface);
          }
!         ~LevelPreviewCacheElem() { delete surface; }
          bool operator<(const LevelPreviewCacheElem& other) { return 
idx<other.idx; }
!         Surface *get_surface() { return surface; }
      };
  
--- 129,280 ----
  
  
+     void savePNG(Surface *surface, const string& fname) {
+         int            h            = surface->height();
+         int            w            = surface->width();
+         unsigned char *rows[h];
+ 
+         surface->lock();
+         for (int i = 0; i<h; ++i) {
+             rows[i] = (unsigned char *)surface->scanline_pointer(i);
+         }
+ 
+         enigma::Log << "Caching auto-preview as '" << fname << '\'' << endl;
+ 
+         string error;
+         FILE *fp    = fopen(fname.c_str(), "wb");
+ 
+         if (fp) {
+             png_structp png_ptr = 
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+             if (!png_ptr) {
+                 error = "write struct not generated";
+             }
+             else {
+                 png_infop info_ptr = png_create_info_struct(png_ptr);
+                 if (!info_ptr) {
+                     error = "info struct not generated";
+                 }
+                 else {
+                     static const char *what = 0;
+                     if (setjmp(png_jmpbuf(png_ptr))) {
+                         error = strf("unknown error during '%s' while 
creating png", what);
+                     }
+                     else {
+                         what = "png_init_io";
+                         png_init_io(png_ptr, fp);
+                         what = "png_set_IHDR";
+                         png_set_IHDR(png_ptr,
+                                      info_ptr,
+                                      w, h,
+                                      8,
+                                      PNG_COLOR_TYPE_RGBA,
+                                      PNG_INTERLACE_NONE,
+                                      PNG_COMPRESSION_TYPE_BASE,
+                                      PNG_FILTER_TYPE_BASE);
+ //                         what = "png_set_compression_level";
+ //                         png_set_compression_level(png_ptr, 9); // nearly 
no effect
+                         what = "png_write_info";
+                         png_write_info(png_ptr, info_ptr);
+ 
+                         png_write_image(png_ptr, rows);
+ 
+                         what = "png_write_end";
+                         png_write_end(png_ptr, NULL);
+                     }
+                 }
+                 // next line frees resources - and it crashes enigma :-(
+                 // png_destroy_write_struct(&png_ptr, &info_ptr);
+             }
+             fclose(fp);
+         }
+         else {
+             error = "Couldn't create file";
+         }
+ 
+         if (error.length() > 0) {
+             fprintf(stderr, "Error saving '%s': %s\n", fname.c_str(), 
error.c_str());
+         }
+ 
+         surface->unlock();
+     }
+ 
+     string removeIllChars(const string& s) {
+         string s2 = s;
+         for (string::iterator c = s2.begin(); c != s2.end(); ++c) {
+             if (!isalnum(*c)) *c = '_';
+         }
+         return s2;
+     }
+ 
+     string gen_preview_name(int revision, int preview_version, const string& 
name) {
+         return px::strf("thumbs/%i_%i_%s.png", revision, preview_version, 
name.c_str());
+     }
+ 
+     void removeOldPreviews(int revision, int preview_version, const string& 
name) {
+         for (int r = revision; r >= 1; --r) {
+             for (int v = preview_version; v >= 1; --v) {
+                 string preview_name = gen_preview_name(r, v, name);
+                 string found_name;
+                 if (FindFile(preview_name, found_name)) {
+                     if (remove(found_name.c_str()) == -1) {
+                         enigma::Log << "Error deleting outdated preview '" << 
found_name << '\'' << endl;
+ //                         fprintf(stderr, "error deleting %s\n", 
found_name.c_str());
+                     }
+                     else {
+                         enigma::Log << "Deleting outdated preview '" << 
found_name << '\'' << endl;
+                     }
+                 }
+             }
+         }
+     }
+ 
+ 
      class LevelPreviewCacheElem {
!         Surface  *surface;      // owned by ImageCache
!         Surface  *zoomed_surface; // owned by LevelPreviewCacheElem
!         unsigned  idx;
  
          LevelPreviewCacheElem(const LevelPreviewCacheElem&);
          LevelPreviewCacheElem& operator = (const LevelPreviewCacheElem& 
other);
      public:
!         LevelPreviewCacheElem(LevelPack *lp, unsigned idx_, int xsize, int 
ysize, ImageCache& img_cache)
!             : surface(0), zoomed_surface(0), idx(idx_)
          {
!             string cleanedName     = 
removeIllChars(lp->get_info(idx)->filename);
!             int    rev_number      = lp->get_revision_number(idx);
!             int    preview_version = lp->get_preview_version();
!             string preview_name    = gen_preview_name(rev_number, 
preview_version, cleanedName);
!             string preview_path;
! 
!             if (FindFile(preview_name, preview_path))
!                 surface = img_cache.get(preview_path);
! 
!             if (!surface) {
!                 Surface *preview = LevelPreview(lp, idx); // do not free, 
points to BackBuffer
!                 if (preview) {
!                     const Rect&  game_area    = display::GetGameArea();
!                     Surface     *game_surface = Grab(preview, game_area);
! 
!                     if (game_surface) {
!                         zoomed_surface = game_surface->zoom(xsize, ysize);
!                         string preview_dir_path = 
FindDataFile("thumbs/README");
!                         string parent_dir;
!                         if (px::split_path(preview_dir_path, &parent_dir, 0)) 
{
!                             string parent_dir2;
!                             if (px::split_path(parent_dir, &parent_dir2, 0)) {
!                                 preview_name = px::concat_paths(parent_dir2, 
preview_name);
!                             }
!                         }
! 
!                         removeOldPreviews(rev_number, preview_version, 
cleanedName);
!                         savePNG(zoomed_surface, preview_name);
!                     }
  
                      delete game_surface;
                  }
              }
          }
!         ~LevelPreviewCacheElem() { delete zoomed_surface; }
          bool operator<(const LevelPreviewCacheElem& other) { return 
idx<other.idx; }
!         Surface *get_surface() { return surface ? surface : zoomed_surface; }
      };
  
***************
*** 161,164 ****
--- 283,287 ----
  
          PreviewMap cache;
+         ImageCache imgCache;
          int        xsize, ysize;
  
***************
*** 183,187 ****
  
              assert(xsize != 0 && ysize != 0); // forgot to call set_size() ?
!             LevelPreviewCacheElem *ce = new LevelPreviewCacheElem(lp, idx, 
xsize, ysize);
  
              Surface *surface = ce->get_surface();
--- 306,310 ----
  
              assert(xsize != 0 && ysize != 0); // forgot to call set_size() ?
!             LevelPreviewCacheElem *ce = new LevelPreviewCacheElem(lp, idx, 
xsize, ysize, imgCache);
  
              Surface *surface = ce->get_surface();





reply via email to

[Prev in Thread] Current Thread [Next in Thread]