Logo
  • Main Page
  • Related Pages
  • Modules
  • Classes
  • Files

mmsimagemanager.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2007 Stefan Schwarzer, Jens Schneider,             *
00003  *                           Matthias Hardt, Guido Madaus                  *
00004  *                                                                         *
00005  *   Copyright (C) 2007-2008 BerLinux Solutions GbR                        *
00006  *                           Stefan Schwarzer & Guido Madaus               *
00007  *                                                                         *
00008  *   Copyright (C) 2009-2013 BerLinux Solutions GmbH                       *
00009  *                                                                         *
00010  *   Authors:                                                              *
00011  *      Stefan Schwarzer   <stefan.schwarzer@diskohq.org>,                 *
00012  *      Matthias Hardt     <matthias.hardt@diskohq.org>,                   *
00013  *      Jens Schneider     <jens.schneider@diskohq.org>,                   *
00014  *      Guido Madaus       <guido.madaus@diskohq.org>,                     *
00015  *      Patrick Helterhoff <patrick.helterhoff@diskohq.org>,               *
00016  *      René Bählkow       <rene.baehlkow@diskohq.org>                     *
00017  *                                                                         *
00018  *   This library is free software; you can redistribute it and/or         *
00019  *   modify it under the terms of the GNU Lesser General Public            *
00020  *   License version 2.1 as published by the Free Software Foundation.     *
00021  *                                                                         *
00022  *   This library is distributed in the hope that it will be useful,       *
00023  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00025  *   Lesser General Public License for more details.                       *
00026  *                                                                         *
00027  *   You should have received a copy of the GNU Lesser General Public      *
00028  *   License along with this library; if not, write to the                 *
00029  *   Free Software Foundation, Inc.,                                       *
00030  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
00031  **************************************************************************/
00032 
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <unistd.h>
00036 #include <string.h>
00037 #include "mmsgui/mmsimagemanager.h"
00038 #include "mmsgui/mmsgifloader.h"
00039 #include "mmsgui/mmsfbmanager.h"
00040 
00041 
00042 MMSImageManager::MMSImageManager(MMSFBLayer *layer) {
00043     if (!layer) {
00044         // use default layer
00045         layer = mmsfbmanager.getGraphicsLayer();
00046     }
00047 
00048     // save layer
00049     this->layer = layer;
00050 
00051     // get the pixelformat, create a little temp surface
00052     this->pixelformat = MMSFB_PF_NONE;
00053     MMSFBSurface *ts;
00054     if (this->layer->createSurface(&ts, 8, 1)) {
00055         // okay, get the pixelformat from surface
00056         ts->getPixelFormat(&this->pixelformat);
00057         delete ts;
00058     }
00059 
00060     // use taff?
00061     this->usetaff = false;
00062     switch (this->pixelformat) {
00063     case MMSFB_PF_ARGB:
00064         this->usetaff = true;
00065         this->taffpf = MMSTAFF_PF_ARGB;
00066         break;
00067     case MMSFB_PF_AiRGB:
00068         this->usetaff = true;
00069         this->taffpf = MMSTAFF_PF_AiRGB;
00070         break;
00071     case MMSFB_PF_AYUV:
00072         this->usetaff = true;
00073         this->taffpf = MMSTAFF_PF_AYUV;
00074         break;
00075     case MMSFB_PF_ARGB4444:
00076         this->usetaff = true;
00077         this->taffpf = MMSTAFF_PF_ARGB4444;
00078         break;
00079     case MMSFB_PF_RGB16:
00080         this->usetaff = true;
00081         this->taffpf = MMSTAFF_PF_RGB16;
00082         break;
00083     case MMSFB_PF_ABGR:
00084         this->usetaff = true;
00085         this->taffpf = MMSTAFF_PF_ABGR;
00086         break;
00087     default:
00088         break;
00089     }
00090 }
00091 
00092 MMSImageManager::~MMSImageManager() {
00093     /* free all surfaces */
00094     for (unsigned int i = 0; i < this->images.size(); i++) {
00095         for (int j = 0; j < this->images.at(i)->sufcount; j++)
00096             if (this->images.at(i)->suf[j].surface)
00097                 delete this->images.at(i)->suf[j].surface;
00098         delete this->images.at(i);
00099     }
00100 }
00101 
00102 
00103 MMSFBSurface *MMSImageManager::getImage(const string &path, const string &filename, MMSIM_DESC_SUF **surfdesc,
00104                                         int mirror_size, bool gen_taff) {
00105     string      imagefile;
00106     MMSIM_DESC  *im_desc = NULL;
00107     int         reload_image = -1;
00108 
00109     // build filename
00110     imagefile = path;
00111     if (imagefile != "") imagefile+= "/";
00112     imagefile += filename;
00113     if (imagefile == "")
00114         return NULL;
00115     if (imagefile.substr(imagefile.size()-1,1)=="/")
00116         return NULL;
00117 
00118     if (gen_taff) {
00119         // check if we have to switch off the taff file generation
00120         if (strToUpr(imagefile.substr(0,7)) == "HTTP://") {
00121             gen_taff = false;
00122         }
00123         else
00124         if (strToUpr(imagefile.substr(0,6)) == "FTP://") {
00125             gen_taff = false;
00126         }
00127     }
00128 
00129     // lock threads
00130     this->lock.lock();
00131 
00132     DEBUGMSG("MMSGUI", "Load request for path=%s, name=%s", path.c_str(), filename.c_str());
00133 
00134     // searching within images list
00135     for (unsigned int i = 0; i < this->images.size(); i++) {
00136         if (this->images.at(i)->imagefile == imagefile) {
00137             // already loaded, check if the file has changed
00138             struct stat statbuf;
00139             if (stat(imagefile.c_str(), &statbuf)==0) {
00140                 if (statbuf.st_mtime != this->images.at(i)->mtime) {
00141                     // file was modified, reload it
00142                     reload_image = (int)i;
00143                     this->images.at(i)->mtime = statbuf.st_mtime;
00144                     break;
00145                 }
00146                 else {
00147                     // do not reload
00148                     DEBUGMSG("MMSGUI", "Reusing already loaded image path=%s, name=%s", path.c_str(), filename.c_str());
00149                     this->images.at(i)->usecount++;
00150                     if (surfdesc)
00151                         *surfdesc = this->images.at(i)->suf;
00152                     this->lock.unlock();
00153                     return this->images.at(i)->suf[0].surface;
00154                 }
00155             }
00156             else {
00157                 // do not reload
00158                 DEBUGMSG("MMSGUI", "Reusing already loaded image path=%s, name=%s", path.c_str(), filename.c_str());
00159                 this->images.at(i)->usecount++;
00160                 if (surfdesc)
00161                     *surfdesc = this->images.at(i)->suf;
00162                 this->lock.unlock();
00163                 return this->images.at(i)->suf[0].surface;
00164             }
00165         }
00166     }
00167 
00168     // init im_desc
00169     im_desc = new MMSIM_DESC;
00170     memset(im_desc->suf, 0, sizeof(im_desc->suf));
00171     im_desc->suf[0].delaytime = im_desc->suf[1].delaytime = MMSIM_DESC_SUF_END;
00172     im_desc->sufcount = 0;
00173     im_desc->loading = false;
00174 
00175     DEBUGMSG("MMSGUI", "Loading image path=%s, name=%s", path.c_str(), filename.c_str());
00176 
00177     // first try to load GIF formated files
00178     if (isGIF(imagefile)) {
00179         // it's an GIF file
00180         im_desc->imagefile = imagefile;
00181 
00182         if (reload_image < 0) {
00183             // get the modification time of the file
00184             struct stat statbuf;
00185             if (stat(imagefile.c_str(), &statbuf)==0)
00186                 im_desc->mtime = statbuf.st_mtime;
00187             else
00188                 im_desc->mtime = 0;
00189         }
00190 
00191         if (reload_image < 0) {
00192             // load it
00193             MMSGIFLoader *gifloader = new MMSGIFLoader(im_desc, this->layer);
00194             gifloader->start();
00195             gifloader->block();
00196 
00197             if (im_desc->sufcount > 0) {
00198                 DEBUGMSG("MMSGUI", "ImageManager has loaded: '%s'", imagefile.c_str());
00199 
00200                 // add to images list and return the surface
00201                 im_desc->usecount = 1;
00202                 this->images.push_back(im_desc);
00203                 if (surfdesc)
00204                     *surfdesc = this->images.at(this->images.size()-1)->suf;
00205                 this->lock.unlock();
00206                 return im_desc->suf[0].surface;
00207             }
00208             else {
00209                 // failed to load
00210                 DEBUGMSG("MMSGUI", "cannot load image file '%s'",imagefile.c_str());
00211                 delete im_desc;
00212                 this->lock.unlock();
00213                 return NULL;
00214             }
00215         }
00216         else {
00217             // increase usecount
00218             this->images.at(reload_image)->usecount++;
00219 
00220 //TODO
00221             delete im_desc;
00222             if (surfdesc)
00223                 *surfdesc = this->images.at(reload_image)->suf;
00224             this->lock.unlock();
00225             return this->images.at(reload_image)->suf[0].surface;
00226         }
00227     }
00228     else {
00229         // failed, try to read from taff?
00230 /*
00231 struct  timeval tv;
00232 gettimeofday(&tv, NULL);
00233 DEBUGMSG("start > %d\n", tv.tv_usec);
00234 */
00235 
00236 
00237 
00238         if (this->usetaff) {
00239             // yes, try with taff
00240             // assume: the taffpf (supported taff pixelformat) is correctly set
00241             // first : try to read taff image without special pixelformat
00242             // second: try with pixelformat from my surfaces
00243             bool retry = false;
00244             MMSTaffFile *tafff = NULL;
00245             do {
00246                 if (retry) {
00247                     retry = false;
00248                     DEBUGMSG("MMSGUI", "ImageManager, retry");
00249 
00250                     // have to convert taff with special destination pixelformat
00251                     if (gen_taff) {
00252                         // here we have to use *.taff file, which should store converted image data
00253                         tafff = new MMSTaffFile(imagefile + ".taff", NULL,
00254                                                 "", MMSTAFF_EXTERNAL_TYPE_IMAGE);
00255                     }
00256                     else {
00257                         // hold converted image data in memory, do NOT write it to an *.taff file
00258                         tafff = new MMSTaffFile("", NULL,
00259                                                 "", MMSTAFF_EXTERNAL_TYPE_IMAGE,
00260                                                 false, false, false, true, false);
00261                     }
00262 
00263                     if (tafff) {
00264                         // set external file and requested pixelformat
00265                         tafff->setExternal(imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE);
00266                         DEBUGMSG("MMSGUI", "ImageManager, taffpf = %d", taffpf);
00267 
00268                         if (config.getGraphicsLayer().outputtype == MMSFB_OT_OGL) {
00269                             // for ogl we don't need premultiplied images
00270                             tafff->setDestinationPixelFormat(taffpf, false);
00271                         }
00272                         else {
00273                             // use premultiplied images
00274                             tafff->setDestinationPixelFormat(taffpf, true);
00275                         }
00276 
00277                         // set mirror size
00278                         tafff->setMirrorEffect(mirror_size);
00279 
00280                         // rotate image by 180°?
00281                         tafff->rotate180(MMSFBBase_rotate180);
00282 
00283                         // convert it
00284                         if (!tafff->convertExternal2TAFF()) {
00285                             // conversion failed
00286                             delete tafff;
00287                             tafff = NULL;
00288                             break;
00289                         }
00290 
00291                         if (gen_taff) {
00292                             // delete this tafff instance, because it will be re-loaded
00293                             delete tafff;
00294                             tafff = NULL;
00295                         }
00296                     }
00297                 }
00298 
00299                 // load image, but do not auto rewrite taff because have to set special attributes like mirror effect
00300                 if (gen_taff) {
00301                     tafff = new MMSTaffFile(imagefile + ".taff", NULL,
00302                                             imagefile, MMSTAFF_EXTERNAL_TYPE_IMAGE,
00303                                             false, false, false, false, false);
00304                 }
00305                 else {
00306                     if (!tafff) {
00307                         retry = true;
00308                         continue;
00309                     }
00310                 }
00311                 if (tafff) {
00312                     if (!tafff->isLoaded()) {
00313                         // set special attributes like mirror effect
00314                         tafff->setMirrorEffect(mirror_size);
00315 
00316                         // rotate image by 180°?
00317                         tafff->rotate180(MMSFBBase_rotate180);
00318 
00319                         // convert it
00320                         if (!tafff->convertExternal2TAFF()) {
00321                             // conversion failed
00322                             delete tafff;
00323                             break;
00324                         }
00325                         delete tafff;
00326                         tafff = NULL;
00327 
00328                         // here we have to read from *.taff file, because special attributes will be written to file
00329                         tafff = new MMSTaffFile(imagefile + ".taff", NULL,
00330                                                 "", MMSTAFF_EXTERNAL_TYPE_IMAGE);
00331                     }
00332                 }
00333                 if (tafff) {
00334                     if (tafff->isLoaded()) {
00335 
00336                         // load the attributes
00337                         int         attrid;
00338                         char        *value_str;
00339                         int         value_int;
00340                         void        *img_buf = NULL;
00341                         int         img_width = 0;
00342                         int         img_height= 0;
00343                         int         img_pitch = 0;
00344                         int         img_size  = 0;
00345                         MMSTAFF_PF  img_pixelformat = MMSTAFF_PF_ARGB;
00346                         bool        img_premultiplied = true;
00347                         int         img_mirror_size = 0;
00348                         bool        img_alphachannel = true;
00349                         bool        img_rotate_180 = false;
00350 
00351                         while ((attrid=tafff->getNextAttribute(&value_str, &value_int, NULL))>=0) {
00352                             switch (attrid) {
00353                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_width:
00354                                 img_width = value_int;
00355                                 break;
00356                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_height:
00357                                 img_height = value_int;
00358                                 break;
00359                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pitch:
00360                                 img_pitch = value_int;
00361                                 break;
00362                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_size:
00363                                 img_size = value_int;
00364                                 break;
00365                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_data:
00366                                 img_buf = value_str;
00367                                 break;
00368                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_pixelformat:
00369                                 img_pixelformat = (MMSTAFF_PF)value_int;
00370                                 break;
00371                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_premultiplied:
00372                                 img_premultiplied = (value_int);
00373                                 break;
00374                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_mirror_size:
00375                                 img_mirror_size = value_int;
00376                                 break;
00377                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_alphachannel:
00378                                 img_alphachannel = (value_int);
00379                                 break;
00380                             case MMSTAFF_IMAGE_RAWIMAGE_ATTR::MMSTAFF_IMAGE_RAWIMAGE_ATTR_IDS_rotate_180:
00381                                 img_rotate_180 = (value_int);
00382                                 break;
00383                             }
00384                         }
00385 
00386                         if (img_pixelformat != taffpf) {
00387                             DEBUGMSG("MMSGUI", "ImageManager, taffpf = %d", (int)taffpf);
00388                             // the image from the file has not the same pixelformat as the surface
00389                             if (!retry) {
00390                                 // retry with surface pixelformat
00391                                 DEBUGMSG("MMSGUI", "ImageManager, request new pixf");
00392                                 retry = true;
00393                                 delete tafff;
00394                                 continue;
00395                             }
00396                             else
00397                                 retry = false;
00398                         }
00399                         else
00400                         if (img_mirror_size != mirror_size) {
00401                             DEBUGMSG("MMSGUI", "ImageManager, mirror_size = %d", (int)mirror_size);
00402                             // the image from the file has not the same mirror_size
00403                             if (!retry) {
00404                                 // retry with given mirror_size
00405                                 DEBUGMSG("MMSGUI", "ImageManager, request new mirror_size");
00406                                 retry = true;
00407                                 delete tafff;
00408                                 continue;
00409                             }
00410                             else
00411                                 retry = false;
00412                         }
00413                         else
00414                         if (img_premultiplied && (config.getGraphicsLayer().outputtype == MMSFB_OT_OGL)) {
00415                             DEBUGMSG("MMSGUI", "ImageManager, premultiplied image");
00416                             // for ogl we don't need premultiplied images
00417                             if (!retry) {
00418                                 // retry without pre-multiplication
00419                                 DEBUGMSG("MMSGUI", "ImageManager, retry without pre-multiplication");
00420                                 retry = true;
00421                                 delete tafff;
00422                                 continue;
00423                             }
00424                             else
00425                                 retry = false;
00426                         }
00427                         else
00428                         if (!img_premultiplied && (config.getGraphicsLayer().outputtype != MMSFB_OT_OGL)) {
00429                             DEBUGMSG("MMSGUI", "ImageManager, image not premultiplied");
00430                             // we use premultiplied images
00431                             if (!retry) {
00432                                 // retry with pre-multiplication
00433                                 DEBUGMSG("MMSGUI", "ImageManager, retry with pre-multiplication");
00434                                 retry = true;
00435                                 delete tafff;
00436                                 continue;
00437                             }
00438                             else
00439                                 retry = false;
00440                         }
00441                         else
00442                         if (img_rotate_180 && !MMSFBBase_rotate180) {
00443                             DEBUGMSG("MMSGUI", "ImageManager, taff image is rotated by 180 degree, but NOT requested");
00444                             if (!retry) {
00445                                 // reset rotation
00446                                 DEBUGMSG("MMSGUI", "ImageManager, reset rotation");
00447                                 retry = true;
00448                                 delete tafff;
00449                                 continue;
00450                             }
00451                             else
00452                                 retry = false;
00453                         }
00454                         else
00455                         if (!img_rotate_180 && MMSFBBase_rotate180) {
00456                             DEBUGMSG("MMSGUI", "ImageManager, taff image is NOT rotated by 180 degree, but requested");
00457                             if (!retry) {
00458                                 // retry with rotation
00459                                 DEBUGMSG("MMSGUI", "ImageManager, rotate 180 degree");
00460                                 retry = true;
00461                                 delete tafff;
00462                                 continue;
00463                             }
00464                             else
00465                                 retry = false;
00466                         }
00467                         else
00468                         if ((img_width)&&(img_height)&&(img_pitch)&&(img_size)&&(img_buf)) {
00469                             // successfully read
00470 //                          DEBUGMSG("ImageManager, use pixf = %d\n", (int)taffpf);
00471                             im_desc->imagefile = imagefile;
00472 
00473                             if (reload_image < 0) {
00474                                 // get the modification time of the file
00475                                 struct stat statbuf;
00476                                 if (stat(imagefile.c_str(), &statbuf)==0)
00477                                     im_desc->mtime = statbuf.st_mtime;
00478                                 else
00479                                     im_desc->mtime = 0;
00480                             }
00481 
00482                             if (reload_image < 0) {
00483 //printf("ImageManager has loaded: '%s'   - %s\n", imagefile.c_str(),(img_alphachannel)?"alpha":"no alpha");
00484                                 // create a surface
00485                                 if (!this->layer->createSurface(&(im_desc->suf[0].surface), img_width, img_height, this->pixelformat)) {
00486                                     DEBUGMSG("MMSGUI", "cannot create surface for image file '%s'", imagefile.c_str());
00487                                     delete im_desc;
00488                                     this->lock.unlock();
00489                                     return NULL;
00490                                 }
00491                                 im_desc->sufcount = 1;
00492 
00493                                 // blit from external buffer to surface
00494                                 im_desc->suf[0].surface->blitBuffer(img_buf, img_pitch, this->pixelformat,
00495                                                                     img_width, img_height, NULL, 0, 0,
00496                                                                     !img_alphachannel);
00497 
00498                                 // free
00499                                 delete tafff;
00500                                 tafff = NULL;
00501 
00502                                 DEBUGMSG("MMSGUI", "ImageManager has loaded: '%s'", imagefile.c_str());
00503 
00504                                 // add to images list and return the surface
00505                                 im_desc->usecount = 1;
00506                                 this->images.push_back(im_desc);
00507                                 if (surfdesc)
00508                                     *surfdesc = this->images.at(this->images.size()-1)->suf;
00509                                 this->lock.unlock();
00510                                 return im_desc->suf[0].surface;
00511                             }
00512                             else {
00513                                 // increase usecount
00514                                 this->images.at(reload_image)->usecount++;
00515 
00516                                 // check if I have to resize the surface
00517                                 int w, h;
00518                                 this->images.at(reload_image)->suf[0].surface->getSize(&w, &h);
00519                                 if ((w != img_width) || (h != img_height))
00520                                     this->images.at(reload_image)->suf[0].surface->resize(img_width, img_height);
00521 
00522                                 // copy img_buf to the surface
00523                                 char *suf_ptr;
00524                                 int suf_pitch;
00525                                 im_desc->suf[0].surface->lock(MMSFB_LOCK_WRITE, (void**)&suf_ptr, &suf_pitch);
00526 
00527                                 if (img_pitch == suf_pitch)
00528                                     // copy in one block
00529                                     memcpy(suf_ptr, img_buf, img_pitch * img_height);
00530                                 else {
00531                                     // copy each line
00532                                     char *img_b = (char*)img_buf;
00533                                     for (int i = 0; i < img_height; i++) {
00534                                         memcpy(suf_ptr, img_b, img_pitch);
00535                                         suf_ptr+=suf_pitch;
00536                                         img_b+=img_pitch;
00537                                     }
00538                                 }
00539                                 im_desc->suf[0].surface->unlock();
00540 
00541                                 // free
00542                                 delete tafff;
00543                                 tafff = NULL;
00544 
00545                                 DEBUGMSG("MMSGUI", "ImageManager has reloaded: '%s'", imagefile.c_str());
00546 
00547                                 // return the surface
00548                                 delete im_desc;
00549                                 if (surfdesc)
00550                                     *surfdesc = this->images.at(reload_image)->suf;
00551                                 this->lock.unlock();
00552                                 return this->images.at(reload_image)->suf[0].surface;
00553                             }
00554                         }
00555                     }
00556 
00557                     // free
00558                     delete tafff;
00559                     tafff = NULL;
00560                 }
00561             } while (retry);
00562         }
00563 
00564 
00565 #ifdef  __HAVE_DIRECTFB__
00566         IDirectFBImageProvider  *imageprovider = NULL;
00567         DFBSurfaceDescription   surface_desc;
00568 
00569         /* failed, try it with DFB providers */
00570         if (!loadImage(&imageprovider, "", imagefile)) {
00571             DEBUGMSG("MMSGUI", "cannot load image file '%s'", imagefile.c_str());
00572             if (reload_image < 0) {
00573                 delete im_desc;
00574                 this->lock.unlock();
00575                 return NULL;
00576             }
00577             else {
00578                 this->images.at(reload_image)->usecount++;
00579                 delete im_desc;
00580                 if (surfdesc)
00581                     *surfdesc = this->images.at(reload_image)->suf;
00582                 this->lock.unlock();
00583                 return this->images.at(reload_image)->suf[0].surface;
00584             }
00585         }
00586         im_desc->imagefile = imagefile;
00587 
00588         if (reload_image < 0) {
00589             /* get the modification time of the file */
00590             struct stat statbuf;
00591             if (stat(imagefile.c_str(), &statbuf)==0)
00592                 im_desc->mtime = statbuf.st_mtime;
00593             else
00594                 im_desc->mtime = 0;
00595         }
00596 
00597 
00598         /* get surface description */
00599         if (imageprovider->GetSurfaceDescription(imageprovider, &surface_desc)!=DFB_OK) {
00600             /* release imageprovider */
00601             imageprovider->Release(imageprovider);
00602             DEBUGMSG("MMSGUI", "cannot read surface desciption from image file '%s'", imagefile.c_str());
00603             if (reload_image < 0) {
00604                 delete im_desc;
00605                 this->lock.unlock();
00606                 return NULL;
00607             }
00608             else {
00609                 this->images.at(reload_image)->usecount++;
00610                 delete im_desc;
00611                 if (surfdesc)
00612                     *surfdesc = this->images.at(reload_image)->suf;
00613                 this->lock.unlock();
00614                 return this->images.at(reload_image)->suf[0].surface;
00615             }
00616         }
00617 
00618         if (reload_image < 0) {
00619             /* create a surface */
00620             if (!this->layer->createSurface(&(im_desc->suf[0].surface), surface_desc.width, surface_desc.height, this->pixelformat)) {
00621                 /* release imageprovider */
00622                 imageprovider->Release(imageprovider);
00623                 DEBUGMSG("MMSGUI", "cannot create surface for image file '%s'", imagefile.c_str());
00624                 delete im_desc;
00625                 this->lock.unlock();
00626                 return NULL;
00627             }
00628             im_desc->sufcount = 1;
00629 
00630             // check if dfb surface available
00631             if (!im_desc->suf[0].surface->getDFBSurface()) {
00632                 /* release imageprovider */
00633                 imageprovider->Release(imageprovider);
00634                 delete im_desc->suf[0].surface;
00635                 DEBUGMSG("MMSGUI", "cannot render image file '%s' because it is not a DFB surface", imagefile.c_str());
00636                 delete im_desc;
00637                 this->lock.unlock();
00638                 return NULL;
00639             }
00640 
00641             /* render to the surface */
00642             if (imageprovider->RenderTo(imageprovider, (IDirectFBSurface *)im_desc->suf[0].surface->getDFBSurface(), NULL)!=DFB_OK) {
00643                 /* release imageprovider */
00644                 imageprovider->Release(imageprovider);
00645                 delete im_desc->suf[0].surface;
00646                 DEBUGMSG("MMSGUI", "cannot render image file '%s'", imagefile.c_str());
00647                 delete im_desc;
00648                 this->lock.unlock();
00649                 return NULL;
00650             }
00651 
00652             /* release imageprovider */
00653             imageprovider->Release(imageprovider);
00654 
00655 /*
00656 gettimeofday(&tv, NULL);
00657 DEBUGMSG("end < %d\n", tv.tv_usec);
00658 */
00659 
00660             DEBUGMSG("MMSGUI", "ImageManager has loaded: '%s'", imagefile.c_str());
00661 
00662             /* add to images list and return the surface */
00663             im_desc->usecount = 1;
00664             this->images.push_back(im_desc);
00665             if (surfdesc)
00666                 *surfdesc = this->images.at(this->images.size()-1)->suf;
00667             this->lock.unlock();
00668             return im_desc->suf[0].surface;
00669         }
00670         else {
00671             /* increase usecount */
00672             this->images.at(reload_image)->usecount++;
00673 
00674             /* check if I have to resize the surface */
00675             int w, h;
00676             this->images.at(reload_image)->suf[0].surface->getSize(&w, &h);
00677             if ((w != surface_desc.width) || (h != surface_desc.height))
00678                 this->images.at(reload_image)->suf[0].surface->resize(surface_desc.width, surface_desc.height);
00679 
00680             /* render to the surface */
00681             if (imageprovider->RenderTo(imageprovider, (IDirectFBSurface *)this->images.at(reload_image)->suf[0].surface->getDFBSurface(), NULL)!=DFB_OK) {
00682                 /* release imageprovider */
00683                 imageprovider->Release(imageprovider);
00684                 DEBUGMSG("MMSGUI", "cannot render image file '%s'", imagefile.c_str());
00685                 delete im_desc;
00686                 if (surfdesc)
00687                     *surfdesc = this->images.at(reload_image)->suf;
00688                 this->lock.unlock();
00689                 return this->images.at(reload_image)->suf[0].surface;
00690             }
00691 
00692             /* release imageprovider */
00693             imageprovider->Release(imageprovider);
00694 
00695             DEBUGMSG("MMSGUI", "ImageManager has reloaded: '%s'", imagefile.c_str());
00696 
00697             /* return the surface */
00698             delete im_desc;
00699             if (surfdesc)
00700                 *surfdesc = this->images.at(reload_image)->suf;
00701             this->lock.unlock();
00702             return this->images.at(reload_image)->suf[0].surface;
00703         }
00704 #endif
00705     }
00706 
00707     this->lock.unlock();
00708     return NULL;
00709 }
00710 
00711 MMSFBSurface *MMSImageManager::newImage(const string &name, unsigned int width, unsigned int height, MMSFBSurfacePixelFormat pixelformat) {
00712 //    DFBSurfaceDescription   desc;
00713     MMSIM_DESC              *im_desc = NULL;
00714 
00715 
00716     // lock threads
00717     this->lock.lock();
00718 
00719     if (name != "") {
00720         /* search name within images list */
00721         for (unsigned int i = 0; i < this->images.size(); i++) {
00722             if (this->images.at(i)->name == name) {
00723                 /* found, must not create a new image */
00724                 this->images.at(i)->usecount++;
00725                 this->lock.unlock();
00726                 return this->images.at(i)->suf[0].surface;
00727             }
00728         }
00729     }
00730 
00731     /* init */
00732     im_desc = new MMSIM_DESC;
00733     memset(im_desc->suf, 0, sizeof(im_desc->suf));
00734     im_desc->suf[0].delaytime = im_desc->suf[1].delaytime = MMSIM_DESC_SUF_END;
00735     im_desc->sufcount = 0;
00736     im_desc->loading = false;
00737 
00738     im_desc->name = name;
00739 
00740 /*    desc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
00741     desc.width = width;
00742     desc.height = height;
00743     desc.pixelformat = pixelformat;
00744 */
00745 //    if (this->dfb->CreateSurface(this->dfb, &desc, &(im_desc.surface)) != DFB_OK)
00746     if (!this->layer->createSurface(&(im_desc->suf[0].surface), width, height, (pixelformat==MMSFB_PF_NONE)?this->pixelformat:pixelformat)) {
00747         this->lock.unlock();
00748         return NULL;
00749     }
00750     im_desc->sufcount = 1;
00751     im_desc->imagefile = "";
00752 
00753     /* add to images list and return the surface */
00754     im_desc->usecount = 1;
00755     this->images.push_back(im_desc);
00756     this->lock.unlock();
00757     return im_desc->suf[0].surface;
00758 }
00759 
00760 void MMSImageManager::releaseImage(const string &path, const string &filename) {
00761     string imagefile;
00762 
00763     /* build filename */
00764     imagefile = path;
00765     if (imagefile != "") imagefile+= "/";
00766     imagefile += filename;
00767     if (imagefile == "")
00768         return;
00769     if (imagefile.substr(imagefile.size()-1,1)=="/")
00770         return;
00771 
00772     // lock threads
00773     this->lock.lock();
00774 
00775     /* search within images list */
00776     for (unsigned int i = 0; i < this->images.size(); i++) {
00777         if (this->images.at(i)->imagefile == imagefile) {
00778             /* surface does exist in memory */
00779             this->images.at(i)->usecount--;
00780             if (this->images.at(i)->usecount <= 0) {
00781                 /* this surface is not used anymore */
00782                 DEBUGMSG("MMSGUI", "ImageManager deletes: '%s'", this->images.at(i)->imagefile.c_str());
00783 
00784                 for (int j = 0; j < this->images.at(i)->sufcount; j++)
00785                     if (this->images.at(i)->suf[j].surface)
00786                         delete this->images.at(i)->suf[j].surface;
00787 
00788                 delete this->images.at(i);
00789                 this->images.erase(this->images.begin()+i);
00790                 break;
00791             }
00792         }
00793     }
00794 
00795     this->lock.unlock();
00796 }
00797 
00798 void MMSImageManager::releaseImage(MMSFBSurface *surface) {
00799     /* NULL? */
00800     if (!surface) return;
00801 
00802     // lock threads
00803     this->lock.lock();
00804 
00805     /* search within images list */
00806     for (unsigned int i = 0; i < this->images.size(); i++) {
00807         if (this->images.at(i)->suf[0].surface == surface) {
00808             /* surface does exist in memory */
00809             this->images.at(i)->usecount--;
00810             if (this->images.at(i)->usecount <= 0) {
00811                 /* this surface is not used anymore */
00812                 DEBUGMSG("MMSGUI", "ImageManager deletes: '%s'", this->images.at(i)->imagefile.c_str());
00813 
00814 //printf("ImageManager deletes: '%s'\n", this->images.at(i)->imagefile.c_str());
00815 
00816                 for (int j = 0; j < this->images.at(i)->sufcount; j++)
00817                     if (this->images.at(i)->suf[j].surface)
00818                         delete this->images.at(i)->suf[j].surface;
00819 
00820                 delete this->images.at(i);
00821                 this->images.erase(this->images.begin()+i);
00822                 break;
00823             }
00824         }
00825     }
00826 
00827     this->lock.unlock();
00828 }
00829 

Generated by doxygen