summaryrefslogtreecommitdiff
path: root/glcdskin/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'glcdskin/cache.c')
-rw-r--r--glcdskin/cache.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/glcdskin/cache.c b/glcdskin/cache.c
new file mode 100644
index 0000000..83629a0
--- /dev/null
+++ b/glcdskin/cache.c
@@ -0,0 +1,177 @@
+/*
+ * GraphLCD skin library
+ *
+ * cache.c - image cache
+ *
+ * This file is released under the GNU General Public License. Refer
+ * to the COPYING file distributed with this package.
+ *
+ */
+
+#include <glcdgraphics/bitmap.h>
+#include <glcdgraphics/image.h>
+#include <glcdgraphics/glcd.h>
+#include <glcdgraphics/pbm.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cache.h"
+#include "skin.h"
+
+namespace GLCD
+{
+
+cImageItem::cImageItem(const std::string & path, cImage * image)
+: path(path),
+ counter(0),
+ image(image)
+{
+}
+
+cImageItem::~cImageItem()
+{
+ delete image;
+}
+
+
+cImageCache::cImageCache(cSkin * Parent, int Size)
+: skin(Parent),
+ size(Size)
+{
+}
+
+cImageCache::~cImageCache()
+{
+ for (unsigned int i = 0; i < images.size(); i++)
+ {
+ delete images[i];
+ }
+ images.clear();
+}
+
+cImage * cImageCache::Get(const std::string & path)
+{
+ std::vector <cImageItem *>::iterator it;
+ cImageItem * item;
+ uint64_t maxCounter;
+ std::vector <cImageItem *>::iterator oldest;
+
+ maxCounter = 0;
+ item = NULL;
+ for (it = images.begin(); it != images.end(); it++)
+ {
+ if (item == NULL && path == (*it)->Path())
+ {
+ (*it)->ResetCounter();
+ item = (*it);
+ }
+ else
+ {
+ (*it)->IncCounter();
+ if ((*it)->Counter() > maxCounter)
+ {
+ maxCounter = (*it)->Counter();
+ oldest = it;
+ }
+ }
+ }
+ if (item)
+ {
+ return item->Image();
+ }
+
+ item = LoadImage(path);
+ if (item)
+ {
+ if (images.size() == size)
+ {
+ images.erase(oldest);
+ }
+ images.push_back(item);
+ return item->Image();
+ }
+ return NULL;
+}
+
+cImageItem * cImageCache::LoadImage(const std::string & path)
+{
+ cImageItem * item;
+ cImage * image;
+ char str[8];
+ int i;
+ int j;
+ std::string file;
+
+ i = path.length() - 1;
+ j = 0;
+ while (i >= 0 && j < 6)
+ {
+ if (path[i] == '.')
+ break;
+ i--;
+ j++;
+ }
+ i++;
+ j = 0;
+ while (i < (int) path.length())
+ {
+ str[j] = toupper((unsigned) path[i]);
+ i++;
+ j++;
+ }
+ str[j] = 0;
+
+ image = new cImage();
+ if (!image)
+ return NULL;
+
+ if (path[0] == '/' || path.find("./") == 0 || path.find("../") == 0)
+ file = path;
+ else
+ {
+ file = skin->Config().SkinPath();
+ if (file.length() > 0)
+ {
+ if (file[file.length() - 1] != '/')
+ file += '/';
+ }
+ file += path;
+ }
+ if (strcmp(str, "PBM") == 0)
+ {
+ cPBMFile pbm;
+
+ if (pbm.Load(*image, file) == false)
+ {
+ delete image;
+ return NULL;
+ }
+ }
+ else if (strcmp(str, "GLCD") == 0)
+ {
+ cGLCDFile glcd;
+
+ if (glcd.Load(*image, file) == false)
+ {
+ delete image;
+ return NULL;
+ }
+ }
+ else
+ {
+ delete image;
+ return NULL;
+ }
+
+ item = new cImageItem(path, image);
+ if (!item)
+ {
+ delete image;
+ return NULL;
+ }
+ return item;
+}
+
+} // end of namespace
+