summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrwastl <mrwastl@users.sourceforge.net>2013-03-21 20:29:45 +0100
committermrwastl <mrwastl@users.sourceforge.net>2013-03-21 20:29:45 +0100
commit60bdec72ecd6bb236f2f1153398c9996fb95730f (patch)
tree7b6a7667f41002b54dcc78360cef71256b811c94
parentcf926629084ab015873859e759155f9bfe813e6b (diff)
downloadgraphlcd-base-60bdec72ecd6bb236f2f1153398c9996fb95730f.tar.gz
graphlcd-base-60bdec72ecd6bb236f2f1153398c9996fb95730f.tar.bz2
glcdgraphics: bug fix in glcd.c, moved methods Scale() and Blend() to image.c, added static methods for loading/saving image; showpic and convpic working again; convpic cleaned up; showpic: added parameters for scaling and centering image
-rw-r--r--glcdgraphics/extformats.c10
-rw-r--r--glcdgraphics/glcd.c25
-rw-r--r--glcdgraphics/image.c189
-rw-r--r--glcdgraphics/image.h10
-rw-r--r--glcdgraphics/imagefile.c122
-rw-r--r--glcdgraphics/imagefile.h6
-rw-r--r--glcdgraphics/pbm.c15
-rw-r--r--graphlcd.conf2
-rw-r--r--tools/convpic/Makefile2
-rw-r--r--tools/convpic/bmp.c378
-rw-r--r--tools/convpic/bmp.h45
-rw-r--r--tools/convpic/convpic.c214
-rw-r--r--tools/convpic/tiff.c203
-rw-r--r--tools/convpic/tiff.h42
-rw-r--r--tools/convpic/tuxbox.c287
-rw-r--r--tools/convpic/tuxbox.h46
-rw-r--r--tools/showpic/showpic.c474
17 files changed, 559 insertions, 1511 deletions
diff --git a/glcdgraphics/extformats.c b/glcdgraphics/extformats.c
index 3a0ab36..5734fce 100644
--- a/glcdgraphics/extformats.c
+++ b/glcdgraphics/extformats.c
@@ -8,7 +8,7 @@
* This file is released under the GNU General Public License. Refer
* to the COPYING file distributed with this package.
*
- * (c) 2011-2012 Wolfgang Astleitner <mrwastl AT users sourceforge net>
+ * (c) 2011-2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
*/
#include <stdio.h>
@@ -66,7 +66,7 @@ bool cExtFormatFile::LoadScaled(cImage & image, const string & fileName, uint16_
std::vector<Magick::Image>::iterator it;
readImages(&extimages, fileName);
if (extimages.size() == 0) {
- syslog(LOG_ERR, "ERROR: graphlcd: Couldn't load %s", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: Couldn't load '%s' (cExtFormatFile::LoadScaled)", fileName.c_str());
return false;
}
@@ -163,16 +163,16 @@ bool cExtFormatFile::LoadScaled(cImage & image, const string & fileName, uint16_
}
}
} catch (Magick::Exception &e) {
- syslog(LOG_ERR, "ERROR: graphlcd: Couldn't load %s: %s", fileName.c_str(), e.what());
+ syslog(LOG_ERR, "glcdgraphics: Couldn't load '%s': %s (cExtFormatFile::LoadScaled)", fileName.c_str(), e.what());
return false;
} catch (...) {
- syslog(LOG_ERR, "ERROR: graphlcd: Couldn't load %s: Unknown exception caught", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: Couldn't load '%s': Unknown exception caught (cExtFormatFile::LoadScaled)", fileName.c_str());
return false;
}
return true;
#else
return false;
-#endif
+#endif
}
// to be done ...
diff --git a/glcdgraphics/glcd.c b/glcdgraphics/glcd.c
index 3b2c3f3..6e97208 100644
--- a/glcdgraphics/glcd.c
+++ b/glcdgraphics/glcd.c
@@ -10,7 +10,7 @@
* to the COPYING file distributed with this package.
*
* (c) 2004-2010 Andreas Regel <andreas.regel AT powarman.de>
- * (c) 2010-2011 Wolfgang Astleitner <mrwastl AT users sourceforge net>
+ * (c) 2010-2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
* Andreas 'randy' Weinberger
*/
@@ -69,7 +69,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
fp = fopen(fileName.c_str(), "rb");
if (!fp)
{
- syslog(LOG_ERR, "glcdgraphics: open %s failed (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: opening of '%s' failed (cGLCDFile::Load).", fileName.c_str());
return false;
}
@@ -98,7 +98,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
// check header sign
if (strncmp(sign, kGLCDFileSign, 3) != 0)
{
- syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: loading of '%s' failed, wrong header (cGLCDFile::Load).", fileName.c_str());
fclose(fp);
return false;
}
@@ -114,7 +114,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
height = (buf[3] << 8) | buf[2];
if (width == 0 || height == 0)
{
- syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: loading of '%s' failed, wrong header (cGLCDFile::Load).", fileName.c_str());
fclose(fp);
return false;
}
@@ -126,7 +126,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
// check file length
if (fileSize != (long) (height * ((width + 7) / 8) + 8))
{
- syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong size (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: loading of '%s' failed, wrong size (cGLCDFile::Load).", fileName.c_str());
fclose(fp);
return false;
}
@@ -136,7 +136,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
// read count and delay
if (fread(buf, 6, 1, fp) != 1)
{
- syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: loading of '%s' failed, wrong header (cGLCDFile::Load).", fileName.c_str());
fclose(fp);
return false;
}
@@ -146,7 +146,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
if (count == 0 ||
fileSize != (long) (count * (height * ((width + 7) / 8)) + 14))
{
- syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong size (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: loading of '%s' failed, wrong size (cGLCDFile::Load).", fileName.c_str());
fclose(fp);
return false;
}
@@ -156,7 +156,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
}
else
{
- syslog(LOG_ERR, "glcdgraphics: load %s failed, wrong header (cGLCDFile::Load).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: loading of '%s' failed, wrong header (cGLCDFile::Load).", fileName.c_str());
fclose(fp);
return false;
}
@@ -213,7 +213,7 @@ bool cGLCDFile::Load(cImage & image, const string & fileName)
if (bmpdata_raw)
delete[] bmpdata_raw;
- syslog(LOG_DEBUG, "glcdgraphics: image %s loaded.", fileName.c_str());
+ syslog(LOG_DEBUG, "glcdgraphics: image '%s' loaded.", fileName.c_str());
return true;
}
@@ -234,7 +234,7 @@ bool cGLCDFile::Save(cImage & image, const string & fileName)
fp = fopen(fileName.c_str(), "wb");
if (!fp)
{
- syslog(LOG_ERR, "glcdgraphics: open %s failed (cGLCDFile::Save).", fileName.c_str());
+ syslog(LOG_ERR, "glcdgraphics: opening '%s' failed (cGLCDFile::Save).", fileName.c_str());
return false;
}
@@ -285,8 +285,7 @@ bool cGLCDFile::Save(cImage & image, const string & fileName)
{
if (bitmap->Width() == width && bitmap->Height() == height)
{
-// if (fwrite(bitmap->Data(), height * ((width + 7) / 8), 1, fp) != 1)
- if (fwrite(bitmap->Data(), height * width, 1, fp) != 1)
+ if (fwrite( cBitmap::ConvertTo1BPP(*bitmap), height * ((width + 7) / 8), 1, fp) != 1)
{
fclose(fp);
return false;
@@ -296,7 +295,7 @@ bool cGLCDFile::Save(cImage & image, const string & fileName)
}
fclose(fp);
- syslog(LOG_DEBUG, "glcdgraphics: image %s saved.", fileName.c_str());
+ syslog(LOG_DEBUG, "glcdgraphics: image '%s' saved.", fileName.c_str());
return true;
}
diff --git a/glcdgraphics/image.c b/glcdgraphics/image.c
index 72003b1..1240b80 100644
--- a/glcdgraphics/image.c
+++ b/glcdgraphics/image.c
@@ -10,11 +10,17 @@
* to the COPYING file distributed with this package.
*
* (c) 2004 Andreas Regel <andreas.regel AT powarman.de>
+ * (c) 2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
*/
#include "bitmap.h"
#include "image.h"
+#include "imagefile.h"
+#include "glcd.h"
+#include "pbm.h"
+#include "extformats.h"
+#include <string.h>
namespace GLCD
{
@@ -64,4 +70,187 @@ void cImage::Clear()
lastChange = 0;
}
+
+uint32_t cImage::Blend(uint32_t FgColour, uint32_t BgColour, uint8_t Level, double antiAliasGranularity) const
+{
+ if (antiAliasGranularity > 0.0)
+ Level = uint8_t(int(Level / antiAliasGranularity + 0.5) * antiAliasGranularity);
+ int Af = (FgColour & 0xFF000000) >> 24;
+ int Rf = (FgColour & 0x00FF0000) >> 16;
+ int Gf = (FgColour & 0x0000FF00) >> 8;
+ int Bf = (FgColour & 0x000000FF);
+ int Ab = (BgColour & 0xFF000000) >> 24;
+ int Rb = (BgColour & 0x00FF0000) >> 16;
+ int Gb = (BgColour & 0x0000FF00) >> 8;
+ int Bb = (BgColour & 0x000000FF);
+ int A = (Ab + (Af - Ab) * Level / 0xFF) & 0xFF;
+ int R = (Rb + (Rf - Rb) * Level / 0xFF) & 0xFF;
+ int G = (Gb + (Gf - Gb) * Level / 0xFF) & 0xFF;
+ int B = (Bb + (Bf - Bb) * Level / 0xFF) & 0xFF;
+ return (A << 24) | (R << 16) | (G << 8) | B;
+}
+
+bool cImage::Scale(uint16_t scalew, uint16_t scaleh, bool AntiAlias)
+{
+ if (! (scalew || scaleh) )
+ return false;
+
+ unsigned int orig_w = Width();
+ unsigned int orig_h = Height();
+
+ // one out of scalew/h == 0 ? -> auto aspect ratio
+ if (scalew && ! scaleh) {
+ scaleh = (uint16_t)( ((uint32_t)scalew * (uint32_t)orig_h) / (uint32_t)orig_w );
+ } else if (!scalew && scaleh) {
+ scalew = (uint16_t)( ((uint32_t)scaleh * (uint32_t)orig_w) / (uint32_t)orig_h );
+ }
+
+ cImage tempImg = cImage();
+ tempImg.SetWidth(scalew);
+ tempImg.SetHeight(scaleh);
+
+ // Scaling/Blending based on VDR / osd.c
+ // Fixed point scaling code based on www.inversereality.org/files/bitmapscaling.pdf
+ // by deltener@mindtremors.com
+ //
+ // slightly improved by Wolfgang Astleitner (modify factors and ratios so that scaled image is centered when upscaling)
+
+ double FactorX, FactorY;
+ int RatioX, RatioY;
+
+ if (!AntiAlias) {
+ FactorX = (double)scalew / (double)orig_w;
+ FactorY = (double)scaleh / (double)orig_h;
+ RatioX = (orig_w << 16) / scalew;
+ RatioY = (orig_h << 16) / scaleh;
+ } else {
+ FactorX = (double)scalew / (double)(orig_w-1);
+ FactorY = (double)scaleh / (double)(orig_h-1);
+ RatioX = ((orig_w-1) << 16) / scalew;
+ RatioY = ((orig_h-1) << 16) / scaleh;
+ }
+
+ bool downscale = (!AntiAlias || (FactorX <= 1.0 && FactorY <= 1.0));
+
+ for (unsigned int frame = 0; frame < Count() ; frame ++ ) {
+ cBitmap *b = new cBitmap(scalew, scaleh, GRAPHLCD_Transparent);
+
+ cBitmap *currFrame = GetBitmap(frame);
+
+ b->SetMonochrome(currFrame->IsMonochrome());
+
+ if (downscale) {
+ // Downscaling - no anti-aliasing:
+ const uint32_t *DestRow = b->Data();
+ int SourceY = 0;
+ for (int y = 0; y < scaleh; y++) {
+ int SourceX = 0;
+ const uint32_t *SourceRow = currFrame->Data() + (SourceY >> 16) * orig_w;
+ uint32_t *Dest = (uint32_t*) DestRow;
+ for (int x = 0; x < scalew; x++) {
+ *Dest++ = SourceRow[SourceX >> 16];
+ SourceX += RatioX;
+ }
+ SourceY += RatioY;
+ DestRow += scalew;
+ }
+ } else {
+ // Upscaling - anti-aliasing:
+ int SourceY = 0;
+ for (int y = 0; y < scaleh /*- 1*/; y++) {
+ int SourceX = 0;
+ int sy = SourceY >> 16;
+ uint8_t BlendY = 0xFF - ((SourceY >> 8) & 0xFF);
+ for (int x = 0; x < scalew /*- 1*/; x++) {
+ int sx = SourceX >> 16;
+ uint8_t BlendX = 0xFF - ((SourceX >> 8) & 0xFF);
+ // TODO: antiAliasGranularity
+ uint32_t c1 = Blend(currFrame->GetPixel(sx, sy), currFrame->GetPixel(sx + 1, sy), BlendX);
+ uint32_t c2 = Blend(currFrame->GetPixel(sx, sy + 1), currFrame->GetPixel(sx + 1, sy + 1), BlendX);
+ uint32_t c3 = Blend(c1, c2, BlendY);
+ b->DrawPixel(x, y, c3);
+ SourceX += RatioX;
+ }
+ SourceY += RatioY;
+ }
+ }
+ tempImg.AddBitmap(b);
+ }
+ // clear all bitmaps from this image
+ unsigned int temp_delay = Delay();
+ Clear();
+ // set new resolution
+ SetWidth(scalew);
+ SetHeight(scaleh);
+ SetDelay(temp_delay);
+ // re-add bitmaps from scaled image container
+ cBitmap * b;
+ cBitmap * tempb;
+ for (unsigned int frame = 0; frame < tempImg.Count(); frame ++) {
+ tempb = tempImg.GetBitmap(frame);
+ b = new cBitmap(scalew, scaleh, (uint32_t*)tempb->Data());
+ b->SetMonochrome(tempb->IsMonochrome());
+ AddBitmap(b);
+ }
+ return true;
+}
+
+
+/* static methods */
+bool cImage::LoadImage(cImage & image, const std::string & fileName) {
+ const std::string fext = GetFilenameExtension(fileName);
+ cImageFile* imgFile = NULL;
+ bool result = true;
+
+ if (fext == "PBM") {
+ imgFile = new cPBMFile();
+ } else if (fext == "GLCD") {
+ imgFile = new cGLCDFile();
+ } else {
+ imgFile = new cExtFormatFile();
+ }
+
+ uint16_t scale_w = 0;
+ uint16_t scale_h = 0;
+
+ if (!imgFile || (imgFile->LoadScaled(image, fileName, scale_w, scale_h) == false) )
+ result = false;
+
+ if (imgFile) delete imgFile;
+ return result;
+}
+
+
+bool cImage::SaveImage(cImage & image, const std::string & fileName) {
+ const std::string fext = GetFilenameExtension(fileName);
+ cImageFile* imgFile = NULL;
+ bool result = false;
+
+ if (fext == "PBM") {
+ imgFile = new cPBMFile();
+ } else if (fext == "GLCD") {
+ imgFile = new cGLCDFile();
+ } else {
+ imgFile = new cExtFormatFile();
+ }
+ if ( imgFile && imgFile->Save(image, fileName) )
+ result = true;
+
+ if (imgFile) delete imgFile;
+ return result;
+}
+
+
+const std::string cImage::GetFilenameExtension(const std::string & fileName) {
+ size_t pos = fileName.find_last_of('.');
+ std::string ext = "";
+ if (pos != std::string::npos) {
+ ext = fileName.substr(pos+1);
+ for (size_t i = 0; i < ext.size(); i++)
+ ext[i] = toupper(ext[i]);
+ }
+ return ext;
+}
+
+
} // end of namespace
diff --git a/glcdgraphics/image.h b/glcdgraphics/image.h
index 888d942..f594886 100644
--- a/glcdgraphics/image.h
+++ b/glcdgraphics/image.h
@@ -10,6 +10,7 @@
* to the COPYING file distributed with this package.
*
* (c) 2004 Andreas Regel <andreas.regel AT powarman.de>
+ * (c) 2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
*/
#ifndef _GLCDGRAPHICS_IMAGE_H_
@@ -18,6 +19,7 @@
#include <stdint.h>
#include <vector>
+#include <string>
namespace GLCD
{
@@ -33,6 +35,8 @@ private:
unsigned int curBitmap;
uint64_t lastChange;
std::vector <cBitmap *> bitmaps;
+
+ uint32_t Blend(uint32_t fgcol, uint32_t bgcol, uint8_t level, double antiAliasGranularity = 0.0) const;
public:
cImage();
~cImage();
@@ -51,6 +55,12 @@ public:
cBitmap * GetBitmap() const;
void AddBitmap(cBitmap * Bitmap) { bitmaps.push_back(Bitmap); }
void Clear();
+
+ bool Scale(uint16_t scalew, uint16_t scaleh, bool AntiAlias = false);
+
+ static bool LoadImage(cImage & image, const std::string & fileName);
+ static bool SaveImage(cImage & image, const std::string & fileName);
+ static const std::string GetFilenameExtension(const std::string & fileName);
};
} // end of namespace
diff --git a/glcdgraphics/imagefile.c b/glcdgraphics/imagefile.c
index b8c6a42..0f9ec25 100644
--- a/glcdgraphics/imagefile.c
+++ b/glcdgraphics/imagefile.c
@@ -7,7 +7,7 @@
* to the COPYING file distributed with this package.
*
* (c) 2006 Andreas Regel <andreas.regel AT powarman.de>
- * (c) 2010-2012 Wolfgang Astleitner <mrwastl AT users sourceforge net>
+ * (c) 2010-2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
*/
#include "image.h"
@@ -35,130 +35,12 @@ bool cImageFile::Save(cImage & image, const std::string & fileName)
}
-uint32_t cImageFile::Blend(uint32_t FgColour, uint32_t BgColour, uint8_t Level, double antiAliasGranularity) const
-{
- if (antiAliasGranularity > 0.0)
- Level = uint8_t(int(Level / antiAliasGranularity + 0.5) * antiAliasGranularity);
- int Af = (FgColour & 0xFF000000) >> 24;
- int Rf = (FgColour & 0x00FF0000) >> 16;
- int Gf = (FgColour & 0x0000FF00) >> 8;
- int Bf = (FgColour & 0x000000FF);
- int Ab = (BgColour & 0xFF000000) >> 24;
- int Rb = (BgColour & 0x00FF0000) >> 16;
- int Gb = (BgColour & 0x0000FF00) >> 8;
- int Bb = (BgColour & 0x000000FF);
- int A = (Ab + (Af - Ab) * Level / 0xFF) & 0xFF;
- int R = (Rb + (Rf - Rb) * Level / 0xFF) & 0xFF;
- int G = (Gb + (Gf - Gb) * Level / 0xFF) & 0xFF;
- int B = (Bb + (Bf - Bb) * Level / 0xFF) & 0xFF;
- return (A << 24) | (R << 16) | (G << 8) | B;
-}
-
-bool cImageFile::Scale(cImage & image, uint16_t scalew, uint16_t scaleh, bool AntiAlias)
-{
- if (! (scalew || scaleh) )
- return false;
-
- // one out of scalew/h == 0 ? -> auto aspect ratio
- if (scalew && ! scaleh) {
- scaleh = (uint16_t)( ((uint32_t)scalew * (uint32_t)image.Height()) / (uint32_t)image.Width() );
- } else if (!scalew && scaleh) {
- scalew = (uint16_t)( ((uint32_t)scaleh * (uint32_t)image.Width()) / (uint32_t)image.Height() );
- }
-
- cImage tempImg = cImage();
- tempImg.SetWidth(scalew);
- tempImg.SetHeight(scaleh);
-
- // Scaling/Blending based on VDR / osd.c
- // Fixed point scaling code based on www.inversereality.org/files/bitmapscaling.pdf
- // by deltener@mindtremors.com
- //
- // slightly improved by Wolfgang Astleitner (modify factors and ratios so that scaled image is centered when upscaling)
-
- double FactorX, FactorY;
- int RatioX, RatioY;
-
- if (!AntiAlias) {
- FactorX = (double)scalew / (double)image.Width();
- FactorY = (double)scaleh / (double)image.Height();
- RatioX = (image.Width() << 16) / scalew;
- RatioY = (image.Height() << 16) / scaleh;
- } else {
- FactorX = (double)scalew / (double)(image.Width()-1);
- FactorY = (double)scaleh / (double)(image.Height()-1);
- RatioX = ((image.Width()-1) << 16) / scalew;
- RatioY = ((image.Height()-1) << 16) / scaleh;
- }
-
- bool downscale = (!AntiAlias || (FactorX <= 1.0 && FactorY <= 1.0));
-
- for (unsigned int frame = 0; frame < image.Count() ; frame ++ ) {
- cBitmap *b = new cBitmap(scalew, scaleh, GRAPHLCD_Transparent);
-
- cBitmap *currFrame = image.GetBitmap(frame);
-
- b->SetMonochrome(currFrame->IsMonochrome());
-
- if (downscale) {
- // Downscaling - no anti-aliasing:
- const uint32_t *DestRow = b->Data();
- int SourceY = 0;
- for (int y = 0; y < scaleh; y++) {
- int SourceX = 0;
- const uint32_t *SourceRow = currFrame->Data() + (SourceY >> 16) * image.Width();
- uint32_t *Dest = (uint32_t*) DestRow;
- for (int x = 0; x < scalew; x++) {
- *Dest++ = SourceRow[SourceX >> 16];
- SourceX += RatioX;
- }
- SourceY += RatioY;
- DestRow += scalew;
- }
- } else {
- // Upscaling - anti-aliasing:
- int SourceY = 0;
- for (int y = 0; y < scaleh /*- 1*/; y++) {
- int SourceX = 0;
- int sy = SourceY >> 16;
- uint8_t BlendY = 0xFF - ((SourceY >> 8) & 0xFF);
- for (int x = 0; x < scalew /*- 1*/; x++) {
- int sx = SourceX >> 16;
- uint8_t BlendX = 0xFF - ((SourceX >> 8) & 0xFF);
- // TODO: antiAliasGranularity
- uint32_t c1 = Blend(currFrame->GetPixel(sx, sy), currFrame->GetPixel(sx + 1, sy), BlendX);
- uint32_t c2 = Blend(currFrame->GetPixel(sx, sy + 1), currFrame->GetPixel(sx + 1, sy + 1), BlendX);
- uint32_t c3 = Blend(c1, c2, BlendY);
- b->DrawPixel(x, y, c3);
- SourceX += RatioX;
- }
- SourceY += RatioY;
- }
- }
- tempImg.AddBitmap(b);
- }
- // clear all bitmaps from image
- image.Clear();
- // set new resolution
- image.SetWidth(scalew);
- image.SetHeight(scaleh);
- // re-add bitmaps from scaled image container
- cBitmap * b;
- cBitmap * tempb;
- for (unsigned int frame = 0; frame < tempImg.Count(); frame ++) {
- tempb = tempImg.GetBitmap(frame);
- b = new cBitmap(scalew, scaleh, (uint32_t*)tempb->Data());
- b->SetMonochrome(tempb->IsMonochrome());
- image.AddBitmap(b);
- }
- return true;
-}
bool cImageFile::LoadScaled(cImage & image, const std::string & fileName, uint16_t & scalew, uint16_t & scaleh)
{
if (Load(image, fileName)) {
if (scalew || scaleh) {
- return Scale(image, scalew, scaleh, true);
+ return image.Scale(scalew, scaleh, true);
} else {
return true;
}
diff --git a/glcdgraphics/imagefile.h b/glcdgraphics/imagefile.h
index 60049ea..fd7dbcc 100644
--- a/glcdgraphics/imagefile.h
+++ b/glcdgraphics/imagefile.h
@@ -7,7 +7,7 @@
* to the COPYING file distributed with this package.
*
* (c) 2006 Andreas Regel <andreas.regel AT powarman.de>
- * (c) 2010-2012 Wolfgang Astleitner <mrwastl AT users sourceforge net>
+ * (c) 2010-2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
*/
#ifndef _GLCDGRAPHICS_IMAGEFILE_H_
@@ -22,10 +22,6 @@ class cImage;
class cImageFile
{
-private:
- uint32_t Blend(uint32_t fgcol, uint32_t bgcol, uint8_t level, double antiAliasGranularity = 0.0) const;
-protected:
- bool Scale(cImage & image, uint16_t scalew, uint16_t scaleh, bool AntiAlias = false);
public:
cImageFile();
virtual ~cImageFile();
diff --git a/glcdgraphics/pbm.c b/glcdgraphics/pbm.c
index d5c0576..3bf94c1 100644
--- a/glcdgraphics/pbm.c
+++ b/glcdgraphics/pbm.c
@@ -7,7 +7,7 @@
* to the COPYING file distributed with this package.
*
* (c) 2006-2010 Andreas Regel <andreas.regel AT powarman.de>
- * (c) 2010-2011 Wolfgang Astleitner <mrwastl AT users sourceforge net>
+ * (c) 2010-2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
* Andreas 'randy' Weinberger
*/
@@ -152,7 +152,7 @@ bool cPBMFile::Load(cImage & image, const std::string & fileName)
return false;
}
fclose(pbmFile);
- syslog(LOG_DEBUG, "glcdgraphics: image %s loaded.", fileName.c_str());
+ syslog(LOG_DEBUG, "glcdgraphics: image '%s' loaded.", fileName.c_str());
return true;
}
@@ -189,7 +189,6 @@ bool cPBMFile::Save(cImage & image, const std::string & fileName)
}
sprintf(str, "P4\n%d %d\n", bitmap->Width(), bitmap->Height());
fwrite(str, strlen(str), 1, fp);
-// fwrite(bitmap->Data(), bitmap->LineSize() * bitmap->Height(), 1, fp);
fwrite(rawdata, rawdata_size, 1, fp);
}
fclose(fp);
@@ -201,10 +200,17 @@ bool cPBMFile::Save(cImage & image, const std::string & fileName)
{
uint16_t i;
char tmpStr[256];
+ size_t pos = fileName.find_last_of('.');
+ std::string fileExt = "";
+ std::string fileBase = fileName;
+ if (pos != std::string::npos) {
+ fileExt = fileName.substr(pos);
+ fileBase = fileName.substr(0, fileName.length() - fileExt.length());
+ }
for (i = 0; i < image.Count(); i++)
{
- sprintf(tmpStr, "%.248s.%05d", fileName.c_str(), i);
+ sprintf(tmpStr, "%.244s-%05d%s", fileBase.c_str(), i, fileExt.c_str());
fp = fopen(tmpStr, "wb");
if (fp)
{
@@ -226,7 +232,6 @@ bool cPBMFile::Save(cImage & image, const std::string & fileName)
}
sprintf(str, "P4\n%d %d\n", bitmap->Width(), bitmap->Height());
fwrite(str, strlen(str), 1, fp);
-// fwrite(bitmap->Data(), bitmap->LineSize() * bitmap->Height(), 1, fp);
fwrite(rawdata, rawdata_size, 1, fp);
}
fclose(fp);
diff --git a/graphlcd.conf b/graphlcd.conf
index 3e28240..625ee12 100644
--- a/graphlcd.conf
+++ b/graphlcd.conf
@@ -22,7 +22,7 @@
# 1 - nanosleep
# 2 - nanosleep (sched_rr) - This is recommended on kernel 2.4 systems
# 3 - gettimeofday - This is recommended on kernel 2.6 systems
-# Defaukt value: 3
+# Default value: 3
WaitMethod=3
# WaitPriority
diff --git a/tools/convpic/Makefile b/tools/convpic/Makefile
index a3a0f6e..6ed0d76 100644
--- a/tools/convpic/Makefile
+++ b/tools/convpic/Makefile
@@ -6,7 +6,7 @@
PRGNAME = convpic
-OBJS = $(PRGNAME).o bmp.o tiff.o tuxbox.o
+OBJS = $(PRGNAME).o
INCLUDES += -I../../
LIBDIRS += -L../../glcdgraphics/
diff --git a/tools/convpic/bmp.c b/tools/convpic/bmp.c
deleted file mode 100644
index 0357988..0000000
--- a/tools/convpic/bmp.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * GraphLCD plugin for the Video Disk Recorder
- *
- * bmp.c - bmp logo class
- *
- * (C) 2004 Andreas Brachold <vdr04 AT deltab de>
- * (C) 2001-2004 Carsten Siebholz <c.siebholz AT t-online de>
- **/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; *
- * if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- ***************************************************************************/
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <cstring>
-#include <cstdlib>
-
-#include <glcdgraphics/bitmap.h>
-#include <glcdgraphics/image.h>
-
-#include "bmp.h"
-
-
-#pragma pack(1)
-typedef struct BMPH {
- uint16_t bmpIdentifier;
- uint32_t bmpFileSize;
- uint32_t bmpReserved;
- uint32_t bmpBitmapDataOffset;
- uint32_t bmpBitmapHeaderSize;
- uint32_t bmpWidth;
- uint32_t bmpHeight;
- uint16_t bmpPlanes;
- uint16_t bmpBitsPerPixel;
- uint32_t bmpCompression;
- uint32_t bmpBitmapDataSize;
- uint32_t bmpHResolution;
- uint32_t bmpVResolution;
- uint32_t bmpColors;
- uint32_t bmpImportantColors;
-} BMPHEADER; // 54 bytes
-
-typedef struct RGBQ {
- uint8_t rgbBlue;
- uint8_t rgbGreen;
- uint8_t rgbRed;
- uint8_t rgbReserved;
-} RGBQUAD; // 4 bytes
-#pragma pack()
-
-
-uint8_t bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-uint8_t bitmaskl[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
-uint8_t bitmaskr[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
-
-cBMPFile::cBMPFile()
-{
-}
-
-cBMPFile::~cBMPFile()
-{
-}
-
-bool cBMPFile::Load(GLCD::cImage & image, const std::string & fileName)
-{
- FILE *fIN;
- BMPHEADER bmpHeader;
- RGBQUAD *pPalette;
- char *pByte;
- char Dummy;
- long iNumColors;
- long iSize;
- uint32_t x, y;
- uint16_t iRead;
-// uint8_t * bitmap = NULL;
- uint32_t *bitmap = NULL;
- bool bInvert = false;
-
- if (fileName.length() > 0)
- {
- fIN = fopen(fileName.c_str(), "rb");
- if (fIN)
- {
- if (fread(&bmpHeader, sizeof(BMPHEADER), 1, fIN)!=1)
- {
- fclose(fIN);
- return false;
- }
-
- // check for Windows BMP
- if (bmpHeader.bmpBitmapHeaderSize != 0x00000028 )
- {
- fprintf(stderr, "ERROR: only Windows BMP images are allowed.\n");
- fclose(fIN);
- return false;
- }
-
- // check for 2 color
- iNumColors = (1 << bmpHeader.bmpBitsPerPixel);
- if (iNumColors != 2)
- {
- fprintf(stderr, "ERROR: the image has %ld colors, but only images with 2 colors are allowed.\n", iNumColors);
- fclose(fIN);
- return false;
- }
-
- iSize = bmpHeader.bmpHeight * bmpHeader.bmpWidth;
-
- pPalette = (RGBQUAD *) malloc( iNumColors*sizeof(RGBQUAD));
- if (!pPalette)
- {
- fprintf(stderr, "ERROR: cannot allocate memory\n");
- fclose(fIN);
- return false;
- }
-
- if (fread( pPalette, iNumColors*sizeof(RGBQUAD), 1, fIN)!=1)
- {
- free(pPalette);
- fclose(fIN);
- return false;
- }
-
- // check colors
- if (pPalette->rgbBlue+pPalette->rgbGreen+pPalette->rgbRed <
- (pPalette+1)->rgbBlue+(pPalette+1)->rgbGreen+(pPalette+1)->rgbRed)
- {
- // index 0 represents 'black', index 1 'white'
- bInvert = !bInvert;
- }
- else
- {
- // index 0 represents 'white', index 1 'black'
- }
-
- if (fseek(fIN, bmpHeader.bmpBitmapDataOffset, SEEK_SET)==EOF)
- {
- free(pPalette);
- fclose(fIN);
- return false;
- }
-
- switch (bmpHeader.bmpCompression)
- {
- case 0: // BI_RGB no compression
- image.Clear();
- image.SetWidth(bmpHeader.bmpWidth);
- image.SetHeight(bmpHeader.bmpHeight);
- image.SetDelay(100);
-// bitmap = new unsigned char[bmpHeader.bmpHeight * ((bmpHeader.bmpWidth + 7) / 8)];
- bitmap = new uint32_t [bmpHeader.bmpHeight * bmpHeader.bmpWidth];
- if (!bitmap)
- {
- fprintf(stderr, "ERROR: cannot allocate memory\n");
- free(pPalette);
- fclose(fIN);
- image.Clear();
- return false;
- }
-
- for (y = bmpHeader.bmpHeight; y > 0; y--)
- {
- pByte = (char*)bitmap + (y-1)*((bmpHeader.bmpWidth+7)/8);
- iRead = 0;
- for (x = 0; x < bmpHeader.bmpWidth / 8; x++)
- {
- if (fread(pByte, sizeof(char), 1, fIN) != 1)
- {
- delete[] bitmap;
- free(pPalette);
- fclose(fIN);
- image.Clear();
- return false;
- }
- iRead++;
- if (bInvert)
- *pByte = *pByte ^ 0xff;
- pByte++;
- }
-
- if (bmpHeader.bmpWidth % 8)
- {
- if (fread(pByte, sizeof(char), 1, fIN) != 1)
- {
- delete [] bitmap;
- free(pPalette);
- fclose(fIN);
- image.Clear();
- return false;
- }
- iRead++;
- if (bInvert)
- *pByte = *pByte^0xff;
- *pByte = *pByte & bitmaskl[bmpHeader.bmpWidth%8];
- pByte++;
- }
-
- // Scan line must be 4-byte-alligned
- while (iRead % 4)
- {
- if (fread(&Dummy, sizeof(char), 1, fIN) != 1)
- {
- delete [] bitmap;
- free(pPalette);
- fclose(fIN);
- image.Clear();
- return false;
- }
- iRead++;
- }
- }
- image.AddBitmap(new GLCD::cBitmap(bmpHeader.bmpWidth, bmpHeader.bmpHeight, bitmap));
- break;
- case 1: // BI_RLE4 RLE 4bit/pixel
- case 2: // BI_RLE8 RLE 8bit/pixel
- case 3: // BI_BITFIELDS
- default:
- fprintf(stderr, "ERROR: only uncompressed RGB images are allowed.\n");
-
- free(pPalette);
- fclose(fIN);
- return false;
- }
- fclose(fIN);
- }
- else
- {
- fprintf(stderr, "ERROR: cannot open picture %s\n", fileName.c_str());
- }
- }
- else
- {
- fprintf(stderr, "ERROR: no FileName given!\n");
- }
- return true;
-}
-
-bool cBMPFile::Save(const GLCD::cBitmap * bitmap, const std::string & fileName)
-{
- FILE *fOut;
- BMPHEADER bmpHeader;
- RGBQUAD bmpColor1, bmpColor2;
- uint32_t dBDO, dBDSx, dBDS;
- char *pByte;
- char Dummy = 0x00;
- uint32_t x, y;
- uint16_t iWrote;
-// const uint8_t * bmpdata = bitmap->Data();
- const uint32_t * bmpdata = bitmap->Data();
-
- if (bitmap
- && bitmap->Width() > 0
- && bitmap->Height() > 0)
- {
- memset(&bmpHeader, 0, sizeof(BMPHEADER));
-
- dBDO = sizeof(BMPHEADER)+2*sizeof(RGBQUAD);
- dBDSx = ((bitmap->Width() + 7) / 8 + 3) & 0xfffffffc;
- dBDS = dBDSx * bitmap->Height();
-
- bmpHeader.bmpIdentifier = 0x4d42; // "BM"
- bmpHeader.bmpFileSize = dBDO + dBDS;
- bmpHeader.bmpBitmapDataOffset = dBDO;
- bmpHeader.bmpBitmapHeaderSize = 0x28;
- bmpHeader.bmpWidth = bitmap->Width();
- bmpHeader.bmpHeight = bitmap->Height();
- bmpHeader.bmpPlanes = 0x01;
- bmpHeader.bmpBitsPerPixel = 0x01;
- bmpHeader.bmpCompression = 0x00;
- bmpHeader.bmpBitmapDataSize = dBDS;
- bmpHeader.bmpHResolution = 0xb13; // 72dpi
- bmpHeader.bmpVResolution = 0xb13; // 72dpi
- bmpHeader.bmpColors = 0x02;
- bmpHeader.bmpImportantColors = 0x02;
-
- bmpColor1.rgbBlue = 0x00;
- bmpColor1.rgbGreen = 0x00;
- bmpColor1.rgbRed = 0x00;
- bmpColor1.rgbReserved = 0x00;
- bmpColor2.rgbBlue = 0xff;
- bmpColor2.rgbGreen = 0xff;
- bmpColor2.rgbRed = 0xff;
- bmpColor2.rgbReserved = 0x00;
-
-
- fOut = fopen(fileName.c_str(), "wb");
- if (!fOut)
- {
- fprintf(stderr,"Cannot create file: %s\n", fileName.c_str());
- return false;
- }
- fwrite(&bmpHeader, sizeof(BMPHEADER), 1, fOut);
- fwrite(&bmpColor1, sizeof(RGBQUAD), 1, fOut);
- fwrite(&bmpColor2, sizeof(RGBQUAD), 1, fOut);
-
- for (y=bitmap->Height(); y>0; y--)
- {
- pByte = (char*)bmpdata + (y-1)*((bitmap->Width()+7)/8);
- iWrote = 0;
- for (x=0; x<(uint32_t) bitmap->Width()/8; x++)
- {
- *pByte = *pByte^0xff;
- if (fwrite(pByte, sizeof(char), 1, fOut)!=1)
- {
- fclose(fOut);
- return false;
- }
- iWrote++;
- pByte++;
- }
- // Scan line must be 4-byte-alligned
- while (iWrote%4)
- {
- if (fwrite(&Dummy, sizeof(char), 1, fOut)!=1)
- {
- fclose(fOut);
- return 3;
- }
- iWrote++;
- }
- }
- fclose(fOut);
- }
- return true;
-}
-
-bool cBMPFile::Save(GLCD::cImage & image, const std::string & fileName)
-{
- const GLCD::cBitmap * bitmap;
-
- if (image.Count() == 1)
- {
- bitmap = image.GetBitmap(0);
- if (bitmap)
- {
- if (!Save(bitmap, fileName))
- {
- return false;
- }
- }
- }
- else
- {
- uint16_t i;
- char tmpStr[256];
-
- for (i = 0; i < image.Count(); i++)
- {
- sprintf(tmpStr, "%.248s.%05d", fileName.c_str(), i);
- bitmap = image.GetBitmap(i);
- if (bitmap)
- {
- if (!Save(bitmap, tmpStr))
- {
- return false;
- }
- }
- }
- }
- return true;
-}
diff --git a/tools/convpic/bmp.h b/tools/convpic/bmp.h
deleted file mode 100644
index 8419838..0000000
--- a/tools/convpic/bmp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * GraphLCD plugin for the Video Disk Recorder
- *
- * bmp.h - bmp logo class
- *
- * (C) 2004 Andreas Brachold <vdr04 AT deltab de>
- * (C) 2001-2004 Carsten Siebholz <c.siebholz AT t-online de>
- **/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; *
- * if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- ***************************************************************************/
-
-#ifndef _BMP_H_
-#define _BMP_H_
-
-#include <glcdgraphics/imagefile.h>
-
-class cBMPFile : public GLCD::cImageFile
-{
-private:
- bool Save(const GLCD::cBitmap * bitmap, const std::string & fileName);
-public:
- cBMPFile();
- virtual ~cBMPFile();
- virtual bool Load(GLCD::cImage & image, const std::string & fileName);
- virtual bool Save(GLCD::cImage & image, const std::string & fileName);
-};
-
-#endif
diff --git a/tools/convpic/convpic.c b/tools/convpic/convpic.c
index 732738c..252b6c8 100644
--- a/tools/convpic/convpic.c
+++ b/tools/convpic/convpic.c
@@ -5,6 +5,7 @@
*
* (C) 2004 Andreas Brachold <vdr04 AT deltab de>
* (C) 2001-2003 by Carsten Siebholz <c.siebholz AT t-online.de>
+ * (C) 2013 Wolfgang Astleitner <mrwastl AT users sourceforge net>
**/
/***************************************************************************
@@ -40,98 +41,41 @@
#include <glcdgraphics/glcd.h>
#include <glcdgraphics/pbm.h>
-#include "bmp.h"
-#include "tiff.h"
-#include "tuxbox.h"
-
static const char *prgname = "convpic";
-static const char *VERSION = "0.1.1";
+static const char *VERSION = "0.1.3";
unsigned int delay = 250;
-enum ePicFormat
-{
- pfUndefined,
- pfTIFF,
- pfBMP,
- pfGLCD,
- pfPBM,
- pfTUXBOX
-};
-
-void usage(void);
-
-ePicFormat getFormat(const char* szFile)
-{
- static const struct tagformats {const char* szExt; ePicFormat picformat;} formats[] =
- {
- {".tiff", pfTIFF },
- {".tif", pfTIFF },
- {".bmp", pfBMP },
- {".glcd", pfGLCD },
- {".pbm", pfPBM },
- {".ani", pfTUXBOX}
- };
- ePicFormat pf = pfUndefined;
-
- if (szFile)
- {
- for (int i = strlen(szFile) - 1; i >= 0; i--)
- {
- if (*(szFile+i) == '.' && strlen(szFile + i + 1))
- {
- for (unsigned int n = 0; n < sizeof(formats)/sizeof(*formats); n++)
- {
- if (!strcasecmp((szFile+i), formats[n].szExt))
- {
- return formats[n].picformat;
- }
- }
- }
- }
- }
- return pf;
+void usage(void) {
+ fprintf(stdout, "\n");
+ fprintf(stdout, "%s v%s\n", prgname, VERSION);
+ fprintf(stdout, "%s is a tool to convert images to a simple format (*.glcd)\n", prgname);
+ fprintf(stdout, " that is used by the graphlcd plugin for VDR.\n\n");
+ fprintf(stdout, " Usage: %s [-n] -i file[s...] -o outfile \n\n", prgname);
+ fprintf(stdout, " -n --invert inverts the output (default: none)\n");
+ fprintf(stdout, " -i --infile specifies the name of the input file[s]\n");
+ fprintf(stdout, " -o --outfile specifies the name of the output file\n");
+ fprintf(stdout, " -d --delay specifies the delay between multiple images [Default: %d ms] \n",delay);
+ fprintf(stdout, "\n" );
+ fprintf(stdout, " example: %s -i vdr-logo.bmp -o vdr-logo.glcd \n", prgname );
}
-GLCD::cImageFile * GetFileTranslator(ePicFormat Format)
-{
- switch (Format)
- {
- case pfGLCD:
- return new GLCD::cGLCDFile();
-
- case pfPBM:
- return new GLCD::cPBMFile();
-
- case pfBMP:
- return new cBMPFile();
-
- case pfTIFF:
- return new cTIFFFile();
-
- case pfTUXBOX:
- return new cTuxBoxFile();
-
- default:
- return NULL;
- }
-
-}
int main(int argc, char *argv[]) {
- ePicFormat inFormat = pfUndefined;
- ePicFormat outFormat = pfUndefined;
std::string inFile = "";
std::string outFile = "";
+ std::string inExtension = "";
+ std::string outExtension = "";
GLCD::cImage image;
GLCD::cImage nextImage;
- GLCD::cImageFile * pInBitmap = NULL;
- GLCD::cImageFile * pOutBitmap = NULL;
bool bError = false;
bool bInvert = false;
bool bDelay = false;
+ unsigned int image_w = 0;
+ unsigned int image_h = 0;
+
static struct option long_options[] =
{
@@ -162,97 +106,108 @@ int main(int argc, char *argv[]) {
bDelay = true;
if (delay < 10)
{
- fprintf(stderr, "Warning: You have specify a to short delay, minimum are 10 ms\n");
+ fprintf(stderr, "WARNING: Delay is too short, minimum delay is 10 ms\n");
delay = 10;
}
break;
default:
+ usage();
return 1;
}
}
- if (inFile.length() == 0)
- {
+ if (inFile.length() == 0) {
fprintf(stderr, "ERROR: You have to specify the infile (-i filename)\n");
bError = true;
}
- if (pfUndefined == (inFormat = getFormat(inFile.c_str())))
- {
- fprintf(stderr, "ERROR: You have to specify a correct extension for the %s\n", inFile.c_str());
+ inExtension = GLCD::cImage::GetFilenameExtension(inFile);
+
+ if (outFile.length() == 0) {
+ outFile = inFile.substr(0, inFile.length() - inExtension.length() - 1);
+ if (inExtension == "GLCD") {
+ outFile += ".pbm";
+ outExtension = "PBM";
+ } else {
+ outFile += ".glcd";
+ outExtension = "GLCD";
+ }
+ fprintf(stderr, "WARNING: No output filename given, will use '%s'\n", outFile.c_str());
+ }
+
+ if (outExtension.length() == 0) {
+ outExtension = GLCD::cImage::GetFilenameExtension(outFile);
+ }
+
+ if ( !(outExtension == "GLCD" || outExtension == "PBM") ) {
+ fprintf(stderr, "ERROR: Unsupported format for outfile ('%s')\n", outExtension.c_str());
bError = true;
}
- if (outFile.length() == 0)
- {
- fprintf(stderr, "ERROR: You have to specify the outfile (-o filename)\n");
+ if ( inExtension != "GLCD" && outExtension != "GLCD" ) {
+ fprintf(stderr, "ERROR: Either infile or outfile needs to be a GLCD file\n");
bError = true;
}
- if (pfUndefined == (outFormat = getFormat(outFile.c_str())))
- {
- fprintf(stderr, "ERROR: You have to specify a correct extension for the %s \n", outFile.c_str());
+ if ( outExtension != "GLCD" && outExtension != "PBM" ) {
+ fprintf(stderr, "ERROR: outfile needs to be either GLCD or PBM\n");
bError = true;
}
- if (bError)
- {
+ if (bError) {
usage();
return 1;
}
-
- pInBitmap = GetFileTranslator(inFormat);
- if (!pInBitmap)
- return 2;
-
- pOutBitmap = GetFileTranslator(outFormat);
- if (!pOutBitmap)
- return 3;
-
// Load Picture
fprintf(stdout, "loading %s\n", inFile.c_str());
- bError = !pInBitmap->Load(image, inFile);
- if (!bError)
- {
+ if (GLCD::cImage::LoadImage(image, inFile) == false) {
+ fprintf(stderr, "ERROR: Failed loading file %s\n", inFile.c_str());
+ bError = true;
+ }
+
+ /* if more than one input image: following images must match width and height of first image */
+ image_w = image.GetBitmap(0)->Width();
+ image_h = image.GetBitmap(0)->Height();
+
+ if (!bError) {
+ GLCD::cImageFile * outImage = NULL;
// Load more in files
- while (optind < argc && !bError)
- {
+ while (optind < argc && !bError) {
inFile = argv[optind++];
- inFormat = getFormat(inFile.c_str());
- if (inFormat == pfUndefined)
- {
- fprintf(stderr, "ERROR: You have to specify a correct extension for the %s\n", inFile.c_str());
- bError = true;
- break;
- }
- pInBitmap = GetFileTranslator(inFormat);
- if (!pInBitmap)
- break;
fprintf(stdout, "loading %s\n", inFile.c_str());
- if (pInBitmap->Load(nextImage, inFile))
- {
+ if (GLCD::cImage::LoadImage(nextImage, inFile) == false) {
+ fprintf(stderr, "ERROR: Failed loading file '%s', ignoring it ...\n", inFile.c_str());
+ } else {
+ unsigned int nim_w = nextImage.GetBitmap(0)->Width();
+ unsigned int nim_h = nextImage.GetBitmap(0)->Height();
+ if ( nim_w != image_w || nim_h != image_h) {
+ fprintf(stderr, "ERROR: Image '%s' is not matching dimensions of first image, ignoring it ...\n", inFile.c_str());
+ } else {
uint16_t i;
- for (i = 0; i < nextImage.Count(); i++)
- {
+ for (i = 0; i < nextImage.Count(); i++) {
image.AddBitmap(new GLCD::cBitmap(*nextImage.GetBitmap(i)));
}
+ }
}
}
if (bDelay)
image.SetDelay(delay);
- if (bInvert)
- {
+ if (bInvert) {
uint16_t i;
- for (i = 0; i < image.Count(); i++)
- {
+ for (i = 0; i < image.Count(); i++) {
image.GetBitmap(i)->Invert();
}
}
+ if (outExtension == "PBM") {
+ outImage = new GLCD::cPBMFile();
+ } else {
+ outImage = new GLCD::cGLCDFile();
+ }
fprintf(stdout, "saving %s\n", outFile.c_str());
- bError = !pOutBitmap->Save(image, outFile);
+ bError = !outImage->Save(image, outFile);
}
if (bError) {
return 4;
@@ -262,18 +217,3 @@ int main(int argc, char *argv[]) {
return 0;
}
-
-void usage(void)
-{
- fprintf(stdout, "\n");
- fprintf(stdout, "%s v%s\n", prgname, VERSION);
- fprintf(stdout, "%s is a tool to convert images to a simple format (*.glcd)\n", prgname);
- fprintf(stdout, " that is used by the graphlcd plugin for VDR.\n\n");
- fprintf(stdout, " Usage: %s [-n] -i file[s...] -o outfile \n\n", prgname);
- fprintf(stdout, " -n --invert inverts the output (default: none)\n");
- fprintf(stdout, " -i --infile specifies the name of the input file[s]\n");
- fprintf(stdout, " -o --outfile specifies the name of the output file\n");
- fprintf(stdout, " -d --delay specifies the delay between multiple images [Default: %d ms] \n",delay);
- fprintf(stdout, "\n" );
- fprintf(stdout, " example: %s -i vdr-logo.bmp -o vdr-logo.glcd \n", prgname );
-}
diff --git a/tools/convpic/tiff.c b/tools/convpic/tiff.c
deleted file mode 100644
index 3eb8cad..0000000
--- a/tools/convpic/tiff.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * GraphLCD plugin for the Video Disk Recorder
- *
- * tiff.c - tiff logo class
- *
- * (c) 2004 Andreas Brachold <vdr04 AT deltab de>
- * (c) 2001-2004 Carsten Siebholz <c.siebholz AT t-online de>
- **/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; *
- * if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- ***************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-
-#include <string>
-
-#include <glcdgraphics/bitmap.h>
-#include <glcdgraphics/image.h>
-
-#include "tiff.h"
-
-
-#pragma pack(1)
-typedef struct TIFFT{
- unsigned short tag;
- unsigned short type;
- unsigned long length;
- /* 1 = BYTE. 8-bit unsigned integer. */
- /* 2 = ASCII. 8-bit bytes that store ASCII codes; the last byte must be null. */
- /* 3 = SHORT. A 16-bit (2-byte) unsigned integer. */
- /* 4 = LONG. A 32-bit (4-byte) unsigned integer. */
- /* 5 = RATIONAL. Two LONGs: the first represents the numerator of a fraction, the second the denominator. */
- unsigned long off_val;
-} TIFFTAG;
-#pragma pack()
-
-#define GETANDCHECK { t=fgetc(fIN);if(t==EOF) {fclose(fIN);return false;};}
-
-cTIFFFile::cTIFFFile()
-{
-}
-
-cTIFFFile::~cTIFFFile()
-{
-}
-
-bool cTIFFFile::Load(GLCD::cImage & image, const std::string & fileName)
-{
- FILE *fIN;
- TIFFTAG tifftag;
- unsigned int tiff_header, tiff_anztags, tiff_data;
- unsigned char cl,ch,y,i;
- unsigned char height, width, strip, invert;
- unsigned char fLittleEndian=0;
- int j;
- int t;
-// unsigned char *bitmap = NULL;
- uint32_t *bitmap = NULL;
- bool bInvert = false;
-
- if (fileName.length() > 0)
- {
- fIN = fopen(fileName.c_str(), "rb");
- if (fIN)
- {
- // isyslog("graphlcd plugin: try to load logo %s.", szFileName);
- if (fseek(fIN, 0, SEEK_SET)==EOF)
- {
- fclose(fIN);
- return false;
- }
- GETANDCHECK; cl=(unsigned char)t;
- GETANDCHECK; ch=(unsigned char)t;
- if ((cl==0x49) && (ch==0x49))
- {
- fLittleEndian=1;
- }
-
- if (fseek(fIN, 4, SEEK_SET)==EOF)
- {
- fclose(fIN);
- return false;
- }
- GETANDCHECK; cl=(unsigned char)t;
- GETANDCHECK; ch=(unsigned char)t;
- tiff_header = cl+256*ch;
- //printf("tiff_header:%d %x\n", tiff_header, tiff_header);
-
- if (fseek(fIN, tiff_header, SEEK_SET)==EOF)
- {
- fclose(fIN);
- return false;
- }
-
- GETANDCHECK; cl=(unsigned char)t;
- GETANDCHECK; ch=(unsigned char)t;
- tiff_anztags = cl+256*ch;
- //printf("tiff_anztags:%d %x\n", tiff_anztags, tiff_anztags);
-
- height=0;
- width=0;
- strip=0;
- invert=0;
- for (i=0; (i<tiff_anztags)&&(!height||!width||!strip||!invert); i++)
- {
- if (fread(&tifftag, sizeof(tifftag), 1, fIN)!=1)
- {
- fclose(fIN);
- return false;
- }
- if (tifftag.tag==0x0100) width=tifftag.off_val;
- if (tifftag.tag==0x0101) height=tifftag.off_val;
- if (tifftag.tag==0x0111) strip=tifftag.off_val;
- if (tifftag.tag==0x0106) invert=tifftag.off_val+1;
- //printf("tag%d: %d %d %ld %ld\n", i,tifftag.tag, tifftag.type, tifftag.length, tifftag.off_val );
- }
-
- if (fseek(fIN,strip, SEEK_SET)==EOF)
- {
- fclose(fIN);
- return false;
- }
- GETANDCHECK; cl=(unsigned char)t;
- GETANDCHECK; ch=(unsigned char)t;
- tiff_data = cl+256*ch;
- //printf("tiff_data:%d %x\n", tiff_data, tiff_data);
-
- if (fseek(fIN, tiff_data, SEEK_SET)==EOF)
- {
- fclose(fIN);
- return false;
- }
-
-
- image.Clear();
- image.SetWidth(width);
- image.SetHeight(height);
- image.SetDelay(100);
-// bitmap = new unsigned char[height * ((width + 7) / 8)];
- bitmap = new uint32_t[height * width];
- if (bitmap)
- {
- if (fread(bitmap, height*((width+7)/8), 1, fIN)!=1)
- {
- delete [] bitmap;
- fclose(fIN);
- image.Clear();
- return false;
- }
-
- if (invert-1==1) bInvert = !bInvert; // 'Black is zero'
- if (bInvert)
- {
- for (j=0; j < height * ((width+7)/8); j++)
- {
- (*(bitmap+j)) = (*(bitmap+j))^0xff;
- }
- }
-
- // cut the rest of the line
- if (width%8)
- {
- for (y=1; y<=height; y++) {
- j=y*((width+7)/8)-1;
- (*(bitmap+j)) = ((*(bitmap+j))>>(8-width%8))<<(8-width%8);
- }
- }
- image.AddBitmap(new GLCD::cBitmap(width, height, bitmap));
- }
- else
- {
- fprintf(stderr, "ERROR: cannot allocate memory\n");
- }
- fclose(fIN);
- }
- else
- {
- fprintf(stderr, "ERROR: cannot open picture %s\n", fileName.c_str());
- }
- }
- else
- {
- fprintf(stderr, "ERROR: no szFileName given!\n");
- }
- return true;
-}
diff --git a/tools/convpic/tiff.h b/tools/convpic/tiff.h
deleted file mode 100644
index f6e66c1..0000000
--- a/tools/convpic/tiff.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * GraphLCD plugin for the Video Disk Recorder
- *
- * tiff.h - tiff logo class
- *
- * (c) 2004 Andreas Brachold <vdr04 AT deltab de>
- * (c) 2001-2004 Carsten Siebholz <c.siebholz AT t-online de>
- **/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; *
- * if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- ***************************************************************************/
-
-#ifndef _TIFF_H_
-#define _TIFF_H_
-
-#include <glcdgraphics/imagefile.h>
-
-class cTIFFFile : public GLCD::cImageFile
-{
-public:
- cTIFFFile();
- virtual ~cTIFFFile();
- virtual bool Load(GLCD::cImage & image, const std::string & fileName);
-};
-
-#endif
diff --git a/tools/convpic/tuxbox.c b/tools/convpic/tuxbox.c
deleted file mode 100644
index 9e3f558..0000000
--- a/tools/convpic/tuxbox.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/**
- * GraphLCD plugin for the Video Disk Recorder
- *
- * tuxbox.c - tuxbox logo class
- *
- * (c) 2004 Andreas Brachold <vdr04 AT deltab de>
- **/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; *
- * if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- ***************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-#include <netinet/in.h>
-
-#include <string>
-
-#include <glcdgraphics/bitmap.h>
-#include <glcdgraphics/image.h>
-
-#include "tuxbox.h"
-
-#pragma pack(1)
-struct ani_header {
- unsigned char magic[4]; // = "LCDA"
- unsigned short format; // Format
- unsigned short width; // Breite
- unsigned short height; // Höhe
- unsigned short count; // Anzahl Einzelbilder
- unsigned long delay; // µs zwischen Einzelbildern
-};
-#pragma pack()
-
-cTuxBoxFile::cTuxBoxFile()
-{
-}
-
-cTuxBoxFile::~cTuxBoxFile()
-{
-}
-
-bool cTuxBoxFile::Load(GLCD::cImage & image, const std::string & fileName)
-{
- bool ret = false;
- FILE * fIN;
- long fileLen;
- struct ani_header header;
- bool bInvert = false;
-
- fIN = fopen(fileName.c_str(), "rb");
- if (fIN)
- {
- // get len of file
- if (fseek(fIN, 0, SEEK_END))
- {
- fclose(fIN);
- return false;
- }
- fileLen = ftell(fIN);
-
- // rewind and get Header
- if (fseek(fIN, 0, SEEK_SET))
- {
- fclose(fIN);
- return false;
- }
-
- // Read header
- if (fread(&header, sizeof(header), 1, fIN) != 1)
- {
- fclose(fIN);
- return false;
- }
-
- image.Clear();
- image.SetWidth(ntohs(header.width));
- image.SetHeight(ntohs(header.height));
- image.SetDelay(ntohl(header.delay) / 1000);
-
- // check Header
- if (strncmp((const char*)header.magic, "LCDA", sizeof(header.magic)) ||
- !image.Width() || !image.Height() || ntohs(header.format) != 0)
- {
- fprintf(stderr, "ERROR: load %s failed, wrong header.\n", fileName.c_str());
- fclose(fIN);
- return false;
- }
-
- //fprintf(stderr,"%d %dx%d (%d %d) %d\n",ntohs(header.count),image.Width(),image.Height(),fileLen, ( (ntohs(header.count) * (image.Width() * ((image.Height() + 7) / 8))) + sizeof(header)),lhdr.delay);
-
- // check file length
- if (!ntohs(header.count)
- || (fileLen != (long) ( (ntohs(header.count) * (image.Width() * ((image.Height() + 7) / 8))) + sizeof(header))))
- {
- fprintf(stderr, "ERROR: load %s failed, wrong size.\n", fileName.c_str());
- fclose(fIN);
- return false;
- }
- // Set minimal limit for next image
- if (image.Delay() < 10)
- image.SetDelay(10);
- for (unsigned int n=0;n<ntohs(header.count);++n)
- {
- ret = false;
-// unsigned int nBmpSize = image.Height() * ((image.Width() + 7) / 8);
- unsigned int nBmpSize = image.Height() * image.Width();
-// unsigned char *bitmap = new unsigned char[nBmpSize];
- uint32_t *bitmap = new uint32_t [nBmpSize];
- if (!bitmap)
- {
- fprintf(stderr, "ERROR: malloc failed.");
- break;
- }
-// unsigned int nAniSize = image.Width() * ((image.Height() + 7) / 8);
- unsigned int nAniSize = image.Width() * image.Height();
-// unsigned char *pAni = new unsigned char[nAniSize];
- uint32_t *pAni = new uint32_t [nAniSize];
- if (!pAni)
- {
- delete[] bitmap;
- fprintf(stderr, "ERROR: malloc failed.");
- break;
- }
-
- if (1 != fread(pAni, nAniSize, 1, fIN))
- {
- fprintf(stderr,"ERROR: Cannot read filedata: %s\n", fileName.c_str());
- delete[] bitmap;
- delete[] pAni;
- break;
- }
-
- vert2horz(pAni,bitmap, image.Width(), image.Height());
- delete[] pAni;
-
- if (bInvert)
- for (unsigned int i=0;i<nBmpSize;++i)
- bitmap[i] ^= 0xFF;
-
- image.AddBitmap(new GLCD::cBitmap(image.Width(), image.Height(), bitmap));
- ret = true;
- }
- fclose(fIN);
- if (!ret)
- image.Clear();
- }
- return ret;
-}
-
-
-bool cTuxBoxFile::Save(GLCD::cImage & image, const std::string & fileName)
-{
- FILE * fOut;
- struct ani_header header;
- bool bRet = false;
-
- if (image.Count() > 0
- && image.Width()
- && image.Height())
- {
- memcpy(header.magic, "LCDA", 4);
- header.format = htons(0);
- header.width = htons(image.Width());
- header.height = htons(image.Height());
- header.count = htons(image.Count());
- header.delay = htonl(image.Delay() * 1000);
-
-
- if (image.Width() != 120 || image.Height() != 64)
- {
- fprintf(stderr,"WARNING: Maybe wrong image dimension (for all I know is 120x64 wanted) %s\n", fileName.c_str());
- }
-
- fOut = fopen(fileName.c_str(), "wb");
- if (!fOut) {
- fprintf(stderr,"ERROR: Cannot create file: %s\n", fileName.c_str());
- return false;
- }
-
- if (1 != fwrite(&header, sizeof(header), 1, fOut))
- {
- fprintf(stderr,"ERROR: Cannot write fileheader: %s\n", fileName.c_str());
- fclose(fOut);
- return false;
- }
-
- for (unsigned int n = 0; n < image.Count(); n++)
- {
- bRet = false;
- unsigned int nAniSize = image.Width() * ((image.Height() + 7) / 8);
-// unsigned char *pAni = new unsigned char[nAniSize];
- uint32_t *pAni = new uint32_t [nAniSize];
- if (!pAni)
- {
- fprintf(stderr, "ERROR: malloc failed.");
- break;
- }
- horz2vert(image.GetBitmap(n)->Data(), pAni, image.Width(), image.Height());
-
- if (1 != fwrite(pAni, nAniSize, 1, fOut))
- {
- delete [] pAni;
- fprintf(stderr,"ERROR: Cannot write filedata: %s\n", fileName.c_str());
- break;
- }
- delete [] pAni;
- bRet = true;
- }
-
- fclose(fOut);
- }
- return bRet;
-}
-
-/** Translate memory alignment from vertical to horizontal
-rotate from {Byte} to {Byte}
-{o}[o][o][o][o][o][o][o] => { oooooooo }
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]
-{o}[o][o][o][o][o][o][o] => [ oooooooo ]*/
-//void cTuxBoxFile::vert2horz(const unsigned char* source, unsigned char* dest, int width, int height) {
-void cTuxBoxFile::vert2horz(const uint32_t *source, uint32_t *dest, int width, int height) {
- int x, y, off;
- memset(dest,0,height*((width+7)/8));
-
- for (y=0; y<height; ++y)
- {
- for (x=0; x<width; ++x)
- {
- off = x + ((y/8) * width);
- if (source[off] & (0x1 << (y % 8)))
- {
- off = (x / 8) + (y * ((width+7)/8));
- dest[off] |= (unsigned char)(0x80 >> (x % 8));
- }
- }
- }
-}
-
-/** Translate memory alignment from horizontal to vertical (rotate byte)
-rotate from {Byte} to {Byte}
-{ oooooooo } => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]
-[ oooooooo ] => {o}[o][o][o][o][o][o][o]*/
-//void cTuxBoxFile::horz2vert(const unsigned char* source, unsigned char* dest, int width, int height) {
-void cTuxBoxFile::horz2vert(const uint32_t *source, uint32_t *dest, int width, int height) {
- int x, y, off;
- memset(dest,0,width*((height+7)/8));
-
- for (y=0; y<height; ++y)
- {
- for (x=0; x<width; ++x)
- {
- off = (x / 8) + ((y) * ((width+7)/8));
- if (source[off] & (0x80 >> (x % 8)))
- {
- off = x + ((y/8) * width);
- dest[off] |= (unsigned char)(0x1 << (y % 8));
- }
- }
- }
-}
diff --git a/tools/convpic/tuxbox.h b/tools/convpic/tuxbox.h
deleted file mode 100644
index 8d19ebd..0000000
--- a/tools/convpic/tuxbox.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * GraphLCD plugin for the Video Disk Recorder
- *
- * tuxbox.h - tuxbox logo class
- *
- * (c) 2004 Andreas Brachold <vdr04 AT deltab de>
- **/
-
-/***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; *
- * if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- ***************************************************************************/
-#ifndef _TUXBOX_H_
-#define _TUXBOX_H_
-
-#include <glcdgraphics/imagefile.h>
-
-class cTuxBoxFile : public GLCD::cImageFile
-{
-private:
-// void vert2horz(const unsigned char* source, unsigned char* dest, int width, int height);
-// void horz2vert(const unsigned char* source, unsigned char* dest, int width, int height);
- void vert2horz(const uint32_t *source, uint32_t *dest, int width, int height);
- void horz2vert(const uint32_t *source, uint32_t *dest, int width, int height);
-public:
- cTuxBoxFile();
- virtual ~cTuxBoxFile();
- virtual bool Load(GLCD::cImage & image, const std::string & fileName);
- virtual bool Save(GLCD::cImage & image, const std::string & fileName);
-};
-
-#endif
diff --git a/tools/showpic/showpic.c b/tools/showpic/showpic.c
index 1c6e213..7c05ca3 100644
--- a/tools/showpic/showpic.c
+++ b/tools/showpic/showpic.c
@@ -20,248 +20,276 @@
#include <getopt.h>
#include <dlfcn.h>
#include <unistd.h>
-#include <syslog.h>
#include <signal.h>
#include <string>
#include <glcdgraphics/bitmap.h>
-#include <glcdgraphics/glcd.h>
#include <glcdgraphics/image.h>
+
#include <glcddrivers/config.h>
#include <glcddrivers/driver.h>
#include <glcddrivers/drivers.h>
-#include <glcdgraphics/extformats.h>
static const char *prgname = "showpic";
-static const char *version = "0.1.2";
+static const char *version = "0.1.3";
static const int kDefaultSleepMs = 100;
static const char * kDefaultConfigFile = "/etc/graphlcd.conf";
static volatile bool stopProgramm = false;
-static void sighandler(int signal)
-{
- switch (signal)
- {
- case SIGINT:
- case SIGQUIT:
- case SIGTERM:
- stopProgramm = true;
- }
+static void sighandler(int signal) {
+ switch (signal) {
+ case SIGINT:
+ case SIGQUIT:
+ case SIGTERM:
+ stopProgramm = true;
+ }
}
-void usage()
-{
- fprintf(stdout, "\n");
- fprintf(stdout, "%s v%s\n", prgname, version);
- fprintf(stdout, "%s is a tool to show an image on an LCD.\n", prgname);
- fprintf(stdout, "The image must be in a special format (*.glcd).\n");
- fprintf(stdout, "You can create such images with the convpic tool.\n\n");
- fprintf(stdout, " Usage: %s [-c CONFIGFILE] [-d DISPLAY] [-s SLEEP] [-uie] file [more files]\n\n", prgname);
- fprintf(stdout, " -c --config specifies the location of the config file\n");
- fprintf(stdout, " (default: /etc/graphlcd.conf)\n");
- fprintf(stdout, " -d --display specifies the output display (default is the first one)\n");
- fprintf(stdout, " -u --upsidedown rotates the output by 180 degrees (default: no)\n");
- fprintf(stdout, " -i --invert inverts the output (default: no)\n");
- fprintf(stdout, " -e --endless show all images in endless loop (default: no)\n");
- fprintf(stdout, " -s --sleep set sleeptime between two images [ms] (default: %d ms)\n", kDefaultSleepMs);
- fprintf(stdout, " -b --brightness set brightness for display (if supported by the driver) [%%]\n");
- fprintf(stdout, " (default: config file value)\n");
- fprintf(stdout, "\n" );
- fprintf(stdout, " examples: %s -c /etc/graphlcd.conf vdr-logo.glcd\n", prgname);
- fprintf(stdout, " %s -c /etc/graphlcd.conf -d LCD_T6963 -u -i vdr-logo.glcd\n", prgname);
- fprintf(stdout, "\n" );
+void usage() {
+ fprintf(stdout, "\n");
+ fprintf(stdout, "%s v%s\n", prgname, version);
+ fprintf(stdout, "%s is a tool to show an image on an LCD.\n", prgname);
+ fprintf(stdout, "The image format must be supported by libglcdgraphics.\n\n");
+ fprintf(stdout, " Usage: %s [-c CONFIGFILE] [-d DISPLAY] [-s SLEEP] [-uie] file [more files]\n\n", prgname);
+ fprintf(stdout, " -c --config specifies the location of the config file\n");
+ fprintf(stdout, " (default: /etc/graphlcd.conf)\n");
+ fprintf(stdout, " -d --display specifies the output display (default is the first one)\n");
+ fprintf(stdout, " -u --upsidedown rotates the output by 180 degrees (default: no)\n");
+ fprintf(stdout, " -i --invert inverts the output (default: no)\n");
+ fprintf(stdout, " -e --endless show all images in endless loop (default: no)\n");
+ fprintf(stdout, " -s --sleep set sleeptime between two images [ms] (default: %d ms)\n", kDefaultSleepMs);
+ fprintf(stdout, " -b --brightness set brightness for display (if supported by the driver) [%%]\n");
+ fprintf(stdout, " (default: config file value)\n");
+ fprintf(stdout, " -S --scale scale algorithm to be used\n");
+ fprintf(stdout, " 0: don't scale (default)\n");
+ fprintf(stdout, " 1: fit to display if larger but not if smaller (keeping aspect ratio) \n");
+ fprintf(stdout, " 2: fit to display if larger or smaller (keeping aspect ratio)\n");
+ fprintf(stdout, " 3: fill display (ignoring aspect ratio)\n");
+ fprintf(stdout, " -C --center center image (default: no)\n");
+ fprintf(stdout, "\n" );
+ fprintf(stdout, " examples: %s -c /etc/graphlcd.conf vdr-logo.glcd\n", prgname);
+ fprintf(stdout, " %s -c /etc/graphlcd.conf -d somedisplay -u -i vdr-animation.glcd\n", prgname);
+ fprintf(stdout, "\n" );
}
-int main(int argc, char *argv[])
-{
- static struct option long_options[] =
- {
- {"config", required_argument, NULL, 'c'},
- {"display", required_argument, NULL, 'd'},
- {"sleep", required_argument, NULL, 's'},
- {"endless", no_argument, NULL, 'e'},
- {"upsidedown", no_argument, NULL, 'u'},
- {"invert", no_argument, NULL, 'i'},
- {"brightness", required_argument, NULL, 'b'},
- {NULL}
- };
-
- std::string configName = "";
- std::string displayName = "";
- bool upsideDown = false;
- bool invert = false;
- int brightness = -1;
- bool delay = false;
- int sleepMs = 100;
- bool endless = false;
- unsigned int displayNumber = 0;
-
- int c, option_index = 0;
- while ((c = getopt_long(argc, argv, "c:d:s:euib:", long_options, &option_index)) != -1)
- {
- switch(c)
- {
- case 'c':
- configName = optarg;
- break;
-
- case 'd':
- displayName = optarg;
- break;
-
- case 'u':
- upsideDown = true;
- break;
-
- case 'i':
- invert = true;
- break;
-
- case 's':
- sleepMs = atoi(optarg);
- delay = true;
- break;
-
- case 'e':
- endless = true;
- break;
-
- case 'b':
- brightness = atoi(optarg);
- if (brightness < 0) brightness = 0;
- if (brightness > 100) brightness = 100;
- break;
-
- default:
- usage();
- return 1;
- }
- }
-
- if (configName.length() == 0)
- {
- configName = kDefaultConfigFile;
- syslog(LOG_INFO, "Error: No config file specified, using default (%s).\n", configName.c_str());
- }
-
- if (GLCD::Config.Load(configName) == false)
- {
- fprintf(stdout, "Error loading config file!\n");
- return 2;
- }
- if (GLCD::Config.driverConfigs.size() > 0)
- {
- if (displayName.length() > 0)
- {
- for (displayNumber = 0; displayNumber < GLCD::Config.driverConfigs.size(); displayNumber++)
- {
- if (GLCD::Config.driverConfigs[displayNumber].name == displayName)
- break;
- }
- if (displayNumber == GLCD::Config.driverConfigs.size())
- {
- fprintf(stdout, "ERROR: Specified display %s not found in config file!\n", displayName.c_str());
- return 3;
- }
- }
- else
- {
- fprintf(stdout, "WARNING: No display specified, using first one.\n");
- displayNumber = 0;
- }
- }
- else
- {
- fprintf(stdout, "ERROR: No displays specified in config file!\n");
- return 4;
- }
-
- if (optind == argc)
- {
- usage();
- fprintf(stderr, "ERROR: You have to specify the image\n");
- return 5;
- }
-
- GLCD::Config.driverConfigs[displayNumber].upsideDown ^= upsideDown;
- GLCD::Config.driverConfigs[displayNumber].invert ^= invert;
- if (brightness != -1)
- GLCD::Config.driverConfigs[displayNumber].brightness = brightness;
- GLCD::cDriver * lcd = GLCD::CreateDriver(GLCD::Config.driverConfigs[displayNumber].id, &GLCD::Config.driverConfigs[displayNumber]);
- if (!lcd)
- {
- fprintf(stderr, "ERROR: Failed creating display object %s\n", displayName.c_str());
- return 6;
- }
- if (lcd->Init() != 0)
- {
- fprintf(stderr, "ERROR: Failed initializing display %s\n", displayName.c_str());
- delete lcd;
- return 7;
- }
- lcd->SetBrightness(GLCD::Config.driverConfigs[displayNumber].brightness);
-
- signal(SIGINT, sighandler);
- signal(SIGQUIT, sighandler);
- signal(SIGTERM, sighandler);
- signal(SIGHUP, sighandler);
-
- const GLCD::cBitmap * bitmap;
- GLCD::cImage image;
- GLCD::cGLCDFile glcd;
- GLCD::cExtFormatFile extformat;
-
- GLCD::cBitmap * buffer = new GLCD::cBitmap(lcd->Width(), lcd->Height());
-
- int optFile;
- std::string picFile;
-
- optFile = optind;
- while (optFile < argc && !stopProgramm)
- {
- picFile = argv[optFile++];
- if (glcd.Load(image, picFile) == false) {
- if (extformat.Load(image, picFile) == false) {
- fprintf(stderr, "ERROR: Failed loading file %s\n", picFile.c_str());
- return 8;
- }
- }
-
- if (delay)
- image.SetDelay(sleepMs);
-
- lcd->Refresh(true);
- while ((bitmap = image.GetBitmap()) != NULL && !stopProgramm)
- {
- buffer->DrawBitmap(0, 0, *bitmap);
- lcd->SetScreen(buffer->Data(), buffer->Width(), buffer->Height());
- lcd->Refresh(false);
-
- if (image.Next(0)) // Select next image
- {
- usleep(image.Delay() * 1000);
- }
- else if (endless && argc == (optind + 1)) // Endless and one and only image
- {
- image.First(0);
- usleep(image.Delay() * 1000);
- }
- else
- break;
- }
-
- if (optFile < argc || endless)
- usleep(sleepMs * 1000);
- if (optFile >= argc && endless)
- optFile = optind;
- }
-
- delete buffer;
- lcd->DeInit();
- delete lcd;
-
- return 0;
+int main(int argc, char *argv[]) {
+ static struct option long_options[] =
+ {
+ {"config", required_argument, NULL, 'c'},
+ {"display", required_argument, NULL, 'd'},
+ {"sleep", required_argument, NULL, 's'},
+ {"endless", no_argument, NULL, 'e'},
+ {"upsidedown", no_argument, NULL, 'u'},
+ {"invert", no_argument, NULL, 'i'},
+ {"brightness", required_argument, NULL, 'b'},
+ {"scale", required_argument, NULL, 'S'},
+ {"center", no_argument, NULL, 'C'},
+ {NULL}
+ };
+
+ std::string configName = "";
+ std::string displayName = "";
+ bool upsideDown = false;
+ bool invert = false;
+ int brightness = -1;
+ bool delay = false;
+ int sleepMs = 100;
+ bool endless = false;
+ unsigned int displayNumber = 0;
+ int scaleAlgo = 0;
+ bool center = false;
+
+ int c, option_index = 0;
+ while ((c = getopt_long(argc, argv, "c:d:s:S:euib:C", long_options, &option_index)) != -1) {
+ switch(c) {
+ case 'c':
+ configName = optarg;
+ break;
+
+ case 'd':
+ displayName = optarg;
+ break;
+
+ case 'u':
+ upsideDown = true;
+ break;
+
+ case 'i':
+ invert = true;
+ break;
+
+ case 's':
+ sleepMs = atoi(optarg);
+ delay = true;
+ break;
+
+ case 'S':
+ scaleAlgo = atoi(optarg);
+ if (scaleAlgo < 0 || scaleAlgo > 3) scaleAlgo = 0;
+ break;
+
+ case 'e':
+ endless = true;
+ break;
+
+ case 'b':
+ brightness = atoi(optarg);
+ if (brightness < 0) brightness = 0;
+ if (brightness > 100) brightness = 100;
+ break;
+
+ case 'C':
+ center = true;
+ break;
+
+ default:
+ usage();
+ return 1;
+ }
+ }
+
+ if (configName.length() == 0) {
+ configName = kDefaultConfigFile;
+ fprintf(stderr, "Error: No config file specified, using default (%s).\n", configName.c_str());
+ }
+
+ if (GLCD::Config.Load(configName) == false) {
+ fprintf(stderr, "Error loading config file!\n");
+ return 2;
+ }
+ if (GLCD::Config.driverConfigs.size() > 0) {
+ if (displayName.length() > 0) {
+ for (displayNumber = 0; displayNumber < GLCD::Config.driverConfigs.size(); displayNumber++) {
+ if (GLCD::Config.driverConfigs[displayNumber].name == displayName)
+ break;
+ }
+ if (displayNumber == GLCD::Config.driverConfigs.size()) {
+ fprintf(stderr, "ERROR: Specified display %s not found in config file!\n", displayName.c_str());
+ return 3;
+ }
+ } else {
+ fprintf(stderr, "WARNING: No display specified, using first one.\n");
+ displayNumber = 0;
+ }
+ } else {
+ fprintf(stderr, "ERROR: No displays specified in config file!\n");
+ return 4;
+ }
+
+ if (optind == argc) {
+ usage();
+ fprintf(stderr, "ERROR: You have to specify the image\n");
+ return 5;
+ }
+
+ GLCD::Config.driverConfigs[displayNumber].upsideDown ^= upsideDown;
+ GLCD::Config.driverConfigs[displayNumber].invert ^= invert;
+ if (brightness != -1)
+ GLCD::Config.driverConfigs[displayNumber].brightness = brightness;
+ GLCD::cDriver * lcd = GLCD::CreateDriver(GLCD::Config.driverConfigs[displayNumber].id, &GLCD::Config.driverConfigs[displayNumber]);
+ if (!lcd) {
+ fprintf(stderr, "ERROR: Failed creating display object %s\n", displayName.c_str());
+ return 6;
+ }
+ if (lcd->Init() != 0) {
+ fprintf(stderr, "ERROR: Failed initializing display %s\n", displayName.c_str());
+ delete lcd;
+ return 7;
+ }
+ lcd->SetBrightness(GLCD::Config.driverConfigs[displayNumber].brightness);
+
+ signal(SIGINT, sighandler);
+ signal(SIGQUIT, sighandler);
+ signal(SIGTERM, sighandler);
+ signal(SIGHUP, sighandler);
+
+ const GLCD::cBitmap * bitmap;
+ GLCD::cImage image;
+
+ GLCD::cBitmap * buffer = new GLCD::cBitmap(lcd->Width(), lcd->Height());
+
+ int optFile;
+ std::string picFile;
+
+ optFile = optind;
+ while (optFile < argc && !stopProgramm) {
+ picFile = argv[optFile++];
+ if (GLCD::cImage::LoadImage(image, picFile) == false) {
+ fprintf(stderr, "ERROR: Failed loading file %s\n", picFile.c_str());
+ return 8;
+ }
+
+ if (scaleAlgo > 0) {
+ uint16_t scalew = 0;
+ uint16_t scaleh = 0;
+ uint16_t imagew = image.Width();
+ uint16_t imageh = image.Height();
+
+ switch (scaleAlgo) {
+ case 1:
+ case 2:
+ if (imagew > lcd->Width() || imageh > lcd->Height()) {
+ if ((double)imagew / (double)lcd->Width() > (double)imageh / (double)lcd->Height())
+ scalew = lcd->Width();
+ else
+ scaleh = lcd->Height();
+ } else if (scaleAlgo == 2 && imagew < lcd->Width() && imageh < lcd->Height()) {
+ if ((double)imagew / (double)lcd->Width() > (double)imageh / (double)lcd->Height())
+ scalew = lcd->Width();
+ else
+ scaleh = lcd->Height();
+ }
+ break;
+ default: /* 3 */
+ scalew = lcd->Width();
+ scaleh = lcd->Height();
+ }
+ image.Scale(scalew, scaleh, false);
+ }
+
+ if (delay)
+ image.SetDelay(sleepMs);
+
+
+ uint16_t xstart = 0;
+ uint16_t ystart = 0;
+
+ if (center) {
+ if ((unsigned int)(lcd->Width()) > image.Width())
+ xstart = (lcd->Width() - image.Width()) >> 1;
+ if ((unsigned int)(lcd->Height()) > image.Height())
+ ystart = (lcd->Height() - image.Height()) >> 1;
+ }
+
+ lcd->Refresh(true);
+ while ((bitmap = image.GetBitmap()) != NULL && !stopProgramm) {
+ buffer->Clear();
+ buffer->DrawBitmap(xstart, ystart, *bitmap);
+ lcd->SetScreen(buffer->Data(), buffer->Width(), buffer->Height());
+ lcd->Refresh(false);
+
+ if (image.Next(0)) { // Select next image
+ usleep(image.Delay() * 1000);
+ } else if (endless && argc == (optind + 1)) { // Endless and one and only image
+ image.First(0);
+ usleep(image.Delay() * 1000);
+ } else {
+ break;
+ }
+ }
+
+ if (optFile < argc || endless)
+ usleep(sleepMs * 1000);
+ if (optFile >= argc && endless)
+ optFile = optind;
+ }
+
+ delete buffer;
+ lcd->DeInit();
+ delete lcd;
+
+ return 0;
}