#include "bitmap.h" #include "setup-image.h" #include #define X_DISPLAY_MISSING #include using namespace Magick; #include #if defined(DEBUG) # ifdef DEBUG # define Dprintf(x...) fprintf(stderr, x) # else # define Dprintf(x...) # endif #else # define Dprintf(x...) #endif cImageCache cImageloadBitmap::mCache(10); void cImageCache::DeleteObject(const tImageSpec &Key, cImageloadBitmap *&Data) { delete Data; } void cImageCache::ResetObject(cImageloadBitmap *&Data) { Data->Reset(); } cImageloadBitmap *cImageloadBitmap::Load(const std::string &Filename, int width, int height, bool ratio, int rotate) { tImageSpec spec(Filename, width, height, ratio); Dprintf("checking image with spec name:%s\nwidth:%d\nheight:%d\nratio:%d\n,rotate;%d\n", Filename.c_str(),width,height,ratio,rotate); std::string fname = Filename; cImageloadBitmap *res = NULL; if (mCache.Contains(spec)) { res = mCache[spec]; Dprintf("Load Image from cache\n"); } else { int pos; if ((pos = fname.find('*')) != -1) { glob_t gbuf; if (glob(fname.c_str(), 0, NULL, &gbuf) == 0){ Dprintf("GLOB: FOUND %s\n", gbuf.gl_pathv[0]); fname = gbuf.gl_pathv[0]; } else { esyslog("ERROR: picselshow: bitmap.c: No match for wildcard filename %s", Filename.c_str()); fname = ""; } globfree(&gbuf); } res = new cImageloadBitmap; int len = fname.length(); bool result = false; if (len > 4) { result = res->LoadImage(fname.c_str(), width, height, ratio, rotate); } else esyslog("ERROR: picselshow: bitmap.c: filename %s too short to identify format", fname.c_str()); Dprintf("..load %sok\n", result ? "" : "not "); if (!result) DELETENULL(res); mCache[spec] = res; } return res; } bool cImageloadBitmap::Available(const std::string &Filename, int width, int height, bool ratio, int rotate) { if ((int)Filename.find('*') != -1) { bool result = false; glob_t gbuf; if (glob(Filename.c_str(), 0, NULL, &gbuf) == 0) result = true; globfree(&gbuf); return result; } else return access(Filename.c_str(), F_OK) == 0; } void cImageloadBitmap::Init(void) { InitializeMagick(NULL); } cImageloadBitmap::cImageloadBitmap(void) { mCurrent = 0; newheight= 0; newwidth = 0; } cImageloadBitmap::~cImageloadBitmap() { for (int i = 0; i < (int)mBitmaps.size(); ++i) delete mBitmaps[i]; mBitmaps.clear(); } cImage &cImageloadBitmap::Get(void) { if (mBitmaps.size() == 1) return *mBitmaps[0]; mCurrent = (mCurrent + 1) % mBitmaps.size(); return *mBitmaps[mCurrent]; } bool cImageloadBitmap::LoadImage(const char *Filename, int width, int height, bool ratio, int rotate) { std::string geometry; std::vector images; cImage *bmp = NULL; try { int w, h; std::vector::iterator it; readImages(&images, Filename); if (images.size() == 0) { esyslog("ERROR: picselshow: bitmap.c: Couldn't load %s", Filename); return false; } // mDelay = images[0].animationDelay() * 10; for (it = images.begin(); it != images.end(); ++it) { if (height != 0 || width != 0) { if(!ratio) { geometry = Geometry(width,height); geometry = geometry + "!"; (*it).filterType(LanczosFilter); // (*it).zoom(geometry); (*it).scale(geometry); } else { switch(rotate) { case 0: break; case 1: //// (*it).rotate(90); break; case 2: //// (*it).rotate(180); break; case 3: //// (*it).rotate(270); break; default: break; } geometry = Geometry(width,height); (*it).filterType(LanczosFilter); // (*it).sample(geometry); (*it).scale(geometry); } } w = (*it).columns(); h = (*it).rows(); bmp = new cImage(cSize(w, h)); newheight = bmp->Height(); newwidth = bmp->Width(); const PixelPacket *pix = (*it).getConstPixels(0, 0, w, h); for (int iy = 0; iy < h; ++iy) { for (int ix = 0; ix < w; ++ix) { tColor col = (~int(pix->opacity * 255 / MaxRGB) << 24) | (int(pix->red * 255 / MaxRGB) << 16) | (int(pix->green * 255 / MaxRGB) << 8) | int(pix->blue * 255 / MaxRGB); bmp->SetPixel(cPoint(ix, iy), col); ++pix; } } mBitmaps.push_back(bmp); } } catch (Exception &e) { esyslog("ERROR: picselshow: bitmap.c: Couldn't load %s: %s", Filename, e.what()); delete bmp; return false; } catch (...) { esyslog("ERROR: picselshow: bitmap.c: Couldn't load %s: Unknown exception caught", Filename); delete bmp; return false; } return true; }