summaryrefslogtreecommitdiffstats
path: root/kernel/kls_iff/fmt_codec_pnm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kls_iff/fmt_codec_pnm.cpp')
-rw-r--r--kernel/kls_iff/fmt_codec_pnm.cpp1470
1 files changed, 1470 insertions, 0 deletions
diff --git a/kernel/kls_iff/fmt_codec_pnm.cpp b/kernel/kls_iff/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_iff/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <ksquirrel@tut.by>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ as32 with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// we will use fork()
+#if defined CODEC_DJVU \
+ || defined CODEC_CAMERA \
+ || defined CODEC_DXF \
+ || defined CODEC_XCF \
+ || defined CODEC_TTF \
+ || defined CODEC_FIG \
+ || defined CODEC_LJPEG \
+ || defined CODEC_NETPBM
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <cstdio>
+#endif
+
+#ifdef CODEC_EPS
+#include <cstdio>
+#include <sstream>
+#include <cmath>
+#endif
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+#include "ksquirrel-libs/fmt_utils.h"
+
+#include "fmt_codec_pnm_defs.h"
+#include "fmt_codec_pnm.h"
+
+#if defined CODEC_CAMERA
+#include "../xpm/codec_camera.xpm"
+#elif defined CODEC_DJVU
+#include "../xpm/codec_djvu.xpm"
+#elif defined CODEC_XCF
+#include "../xpm/codec_xcf.xpm"
+#elif defined CODEC_DXF
+#include "../xpm/codec_dxf.xpm"
+#elif defined CODEC_NEO
+#include "../xpm/codec_neo.xpm"
+#elif defined CODEC_LEAF
+#include "../xpm/codec_leaf.xpm"
+#elif defined CODEC_PI1
+#include "../xpm/codec_pi1.xpm"
+#elif defined CODEC_PI3
+#include "../xpm/codec_pi3.xpm"
+#elif defined CODEC_XIM
+#include "../xpm/codec_xim.xpm"
+#elif defined CODEC_UTAH
+#include "../xpm/codec_utah.xpm"
+#elif defined CODEC_PICT
+#include "../xpm/codec_pict.xpm"
+#elif defined CODEC_IFF
+#include "../xpm/codec_iff.xpm"
+#elif defined CODEC_MAC
+#include "../xpm/codec_mac.xpm"
+#elif defined CODEC_TTF
+#include "../xpm/codec_ttf.xpm"
+#elif defined CODEC_FIG
+#include "../xpm/codec_fig.xpm"
+#elif defined CODEC_LJPEG
+#include "../xpm/codec_ljpeg.xpm"
+#elif defined CODEC_EPS
+#include "../xpm/codec_eps.xpm"
+#else
+#include "../xpm/codec_pnm.xpm"
+#endif
+
+/*
+ *
+ * PBM, PGM,
+ * PNM, and PPM are
+ * intermediate formats used in the conversion of many little known
+ * formats via pbmplus, the Portable Bitmap Utilities. These
+ * formats are mainly available under UNIX and
+ * on Intel-based PCs.
+ *
+ */
+
+static RGB palmono[2] = {RGB(255,255,255), RGB(0,0,0)};
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{
+#ifdef CODEC_DXF
+ std::string tmmp = tmp + ".ppm";
+ unlink(tmmp.c_str());
+#endif
+}
+
+void fmt_codec::options(codec_options *o)
+{
+#if defined CODEC_CAMERA
+ o->version = "8.77"; // dcraw version
+ o->name = "Photos from different cameras";
+ o->filter = "*.arw *.bay *.bmq *.cr2 *.crw *.cs1 *.dc2 *.dcr *.dng *.erf *.fff *.hdr *.ia *.k25 *.kc2 *.kdc *.mdc *.mos *.mrw *.nef *.orf *.pef *.pxn *.raf *.raw *.rdc *.sr2 *.srf *.sti *.x3f ";
+ o->config = std::string(CAMERA_UI);
+ o->mime = "";
+ o->mimetype = "image/x-raw";
+ o->pixmap = codec_camera;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DJVU
+ o->version = "1.0.0";
+ o->name = "DjVu Document";
+ o->filter = "*.djvu *.djv *.iw4 *.iw44 ";
+ o->config = std::string(DJVU_UI);
+ o->mime = "";
+ o->mimetype = "image/x-djvu;image/x.djvu";
+ o->pixmap = codec_djvu;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_DXF
+ o->version = "1.0.0";
+ o->name = "AutoCAD/QCAD Drawing";
+ o->filter = "*.dxf ";
+ o->config = std::string(DXF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-dxf";
+ o->pixmap = codec_dxf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XCF
+ o->version = "1.0.0";
+ o->name = "GIMP XCF";
+ o->filter = "*.xcf ";
+ o->config = std::string(XCF_UI);
+ o->mime = "";
+ o->mimetype = "image/x-xcf-gimp";
+ o->pixmap = codec_xcf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_NEO
+ o->version = "1.0.0";
+ o->name = "Neochrome NEO";
+ o->filter = "*.neo ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-neo";
+ o->pixmap = codec_neo;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LEAF
+ o->version = "1.0.0";
+ o->name = "ILEAF Image";
+ o->filter = "*.leaf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-leaf";
+ o->pixmap = codec_leaf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI1
+ o->version = "1.0.0";
+ o->name = "Degas PI1";
+ o->filter = "*.pi1 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi1";
+ o->pixmap = codec_pi1;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PI3
+ o->version = "1.0.0";
+ o->name = "Degas PI3";
+ o->filter = "*.pi3 ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pi3";
+ o->pixmap = codec_pi3;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_XIM
+ o->version = "1.0.0";
+ o->name = "X IMage";
+ o->filter = "*.xim ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xim";
+ o->pixmap = codec_xim;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_UTAH
+ o->version = "1.0.0";
+ o->name = "UTAH RLE";
+ o->filter = "*.rle ";
+ o->config = "";
+ o->mime = "\x0052\x00CC";
+ o->mimetype = "image/x-utah";
+ o->pixmap = codec_utah;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_PICT
+ o->version = "1.0.0";
+ o->name = "Macintosh PICT";
+ o->filter = "*.pict ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-pict";
+ o->pixmap = codec_pict;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_IFF
+ o->version = "1.0.0";
+ o->name = "Interchange File Format";
+ o->filter = "*.iff *.ilbm *.lbm ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-iff";
+ o->pixmap = codec_iff;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_MAC
+ o->version = "1.0.0";
+ o->name = "Macintosh Paint";
+ o->filter = "*.mac ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-mac";
+ o->pixmap = codec_mac;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_FIG
+ o->version = "0.1.0";
+ o->name = "XFIG";
+ o->filter = "*.fig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-xfig";
+ o->pixmap = codec_fig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_TTF
+ o->version = "0.3.0";
+ o->name = "TrueType and Other Fonts";
+ o->filter = "*.ttf *.ttc *.pfa *.pfb *.otf ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "application/x-font-ttf;application/x-font-ttc;application/x-font-otf;application/x-font-type1";
+ o->pixmap = codec_ttf;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_LJPEG
+ o->version = "0.1.0";
+ o->name = "Lossless JPEG";
+ o->filter = "*.ljpg *.ljpeg ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/ljpeg";
+ o->pixmap = codec_ljpeg;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#elif defined CODEC_EPS
+ o->version = "0.1.0";
+ o->name = "Encapsulated PostScript";
+ o->filter = "*.eps ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-eps";
+ o->pixmap = codec_eps;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+#else
+ o->version = "0.6.4";
+ o->name = "Portable aNy Map";
+ o->filter = "*.pnm *.pgm *.pbm *.ppm ";
+ o->config = "";
+ o->mime = "P[123456]";
+ o->mimetype = "image/x-portable-bitmap;image/x-portable-greymap;image/x-portable-pixmap";
+ o->pixmap = codec_pnm;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = true;
+ o->writeanimated = false;
+ o->needtempfile = false;
+#endif
+}
+
+#if defined CODEC_CAMERA
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // scale factor in percents
+ val.type = settings_value::v_bool;
+
+ val.bVal = true;
+ m_settings["half_size"] = val;
+ m_settings["automatic_white"] = val;
+ m_settings["camera_white"] = val;
+
+ val.bVal = false;
+ m_settings["dontstretch"] = val;
+ m_settings["camera_date"] = val;
+ m_settings["document_mode"] = val;
+ m_settings["interpolate_rggb"] = val;
+ m_settings["icc_cam"] = val;
+ m_settings["embedded_cm"] = val;
+
+ val.type = settings_value::v_int;
+ val.iVal = 0;
+ m_settings["highlights"] = val;
+ m_settings["different"] = val;
+ m_settings["flipping"] = val; // 0 means camera settings
+
+ val.iVal = 0; // 1,2,3 are accepted numbers. 1 means no interpolation
+ m_settings["quick"] = val;
+ val.iVal = -1; // don't use black pixel
+ m_settings["black"] = val;
+ val.iVal = 99; // values 100...1000 are accepted. 99 means no threshold
+ m_settings["threshold"] = val;
+ val.iVal = 1;
+ m_settings["brightness"] = val;
+
+ val.type = settings_value::v_string;
+ val.sVal = "";
+ m_settings["icc_file"] = val;
+}
+#elif defined CODEC_DJVU
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 1;
+ m_settings["page"] = val;
+
+ val.iVal = 2;
+ m_settings["scaledown"] = val;
+}
+#elif defined CODEC_DXF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // page number
+ val.type = settings_value::v_int;
+
+ val.iVal = 0;
+ m_settings["width"] = val;
+ val.iVal = 0;
+ m_settings["height"] = val;
+}
+#elif defined CODEC_XCF
+void fmt_codec::fill_default_settings()
+{
+ settings_value val;
+
+ // background color
+ val.type = settings_value::v_string;
+ val.sVal = "#ffffff";
+ m_settings["background"] = val;
+
+ val.type = settings_value::v_bool;
+ val.bVal = false;
+ m_settings["autocrop"] = val;
+}
+#endif
+
+#ifdef CODEC_EPS
+
+/*
+ * Stolen from KImageIO EPS plugin from kdelibs-3.4.0, which is
+ * under GNU LGPL
+ */
+
+#define BUFLEN 200
+
+#define BBOX "%%BoundingBox:"
+#define BBOX_LEN strlen(BBOX)
+
+static bool seekToCodeStart(ifstreamK *io, size_t &ps_offset, size_t &ps_size)
+{
+ char buf[4]; // We at most need to read 4 bytes at a time
+ ps_offset = 0L;
+ ps_size = 0L;
+
+ if(!io->readK(buf, 2)) // Read first two bytes
+ return false;
+
+ if(buf[0]=='%' && buf[1]=='!') // Check %! magic
+ {
+ }
+ else if(buf[0] == char(0xc5) && buf[1] == char(0xd0)) // Check start of MS-DOS EPS magic
+ { // May be a MS-DOS EPS file
+ if(!io->readK(buf+2, 2)) // Read further bytes of MS-DOS EPS magic
+ return false;
+
+ if(buf[2] == char(0xd3) && buf[3] == char(0xc6)) // Check last bytes of MS-DOS EPS magic
+ {
+ if(!io->readK(buf, 4)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_offset // Offset is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if (!io->readK(buf, 4)) // Get size of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ ps_size // Size is in little endian
+ = ((unsigned char) buf[0])
+ + ((unsigned char) buf[1] << 8)
+ + ((unsigned char) buf[2] << 16)
+ + ((unsigned char) buf[3] << 24);
+
+ if(!io->seekg(ps_offset, ios::beg)) // Get offset of PostScript code in the MS-DOS EPS file.
+ return false;
+
+ if(!io->readK(buf, 2)) // Read first two bytes of what should be the Postscript code
+ return false;
+
+ if(buf[0] != '%' || buf[1] != '!') // Check %! magic
+ return false;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static bool bbox(ifstreamK *io, int *x1, int *y1, int *x2, int *y2)
+{
+ char buf[BUFLEN+1];
+
+ bool ret = false;
+
+ while(io->getline(buf, BUFLEN).good() && strlen(buf))
+ {
+ if(strncmp(buf, BBOX, BBOX_LEN) == 0)
+ {
+ // Some EPS files have non-integer values for the bbox
+ // We don't support that currently, but at least we parse it
+ float _x1, _y1, _x2, _y2;
+
+ if(sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4)
+ {
+ *x1 = (int)_x1;
+ *y1 = (int)_y1;
+ *x2 = (int)_x2;
+ *y2 = (int)_y2;
+
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#endif
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ fptr = 0;
+
+#if defined CODEC_CAMERA
+ std::vector<std::string> params;
+ int status;
+
+ bool half_size,
+ dontstretch,
+ camera_date,
+ automatic_white,
+ camera_white,
+ document_mode,
+ interpolate_rggb,
+ icc_cam,
+ embedded_cm;
+
+ int quick,
+ threshold,
+ black,
+ different,
+ highlights,
+ flipping,
+ brightness;
+
+ std::string icc_file;
+
+ fmt_settings::iterator it = m_settings.find("half_size");
+ half_size = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("icc_cam");
+ icc_cam = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("embedded_cm");
+ embedded_cm = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("dontstretch");
+ dontstretch = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("camera_date");
+ camera_date = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("automatic_white");
+ automatic_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("camera_white");
+ camera_white = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ true : (*it).second.bVal;
+
+ it = m_settings.find("document_mode");
+ document_mode = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("interpolate_rggb");
+ interpolate_rggb = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ it = m_settings.find("quick");
+ quick = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(quick < 0 || quick > 3)
+ quick = 0;
+
+ it = m_settings.find("highlights");
+ highlights = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(highlights < 0 || highlights > 9)
+ highlights = 0; // revert to default value
+
+ it = m_settings.find("flipping");
+ flipping = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(flipping != 0 && flipping != 1 && flipping != 3 && flipping != 5 && flipping != 6)
+ flipping = 0; // revert to default value
+
+ it = m_settings.find("black");
+ black = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ -1 : (*it).second.iVal;
+
+ if(black < -1 || black > 255)
+ black = -1;
+
+ it = m_settings.find("different");
+ different = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ if(different < 0 || different > 99)
+ different = 0; // revert to default
+
+ it = m_settings.find("threshold");
+ threshold = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 100 : (*it).second.iVal;
+
+ if(threshold < 99 || threshold > 1000)
+ threshold = 99; // revert to default
+
+ it = m_settings.find("brightness");
+ brightness = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ if(brightness < 1 || brightness > 255)
+ brightness = 1;
+
+ it = m_settings.find("icc_file");
+ icc_file = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "" : (*it).second.sVal;
+
+ if(embedded_cm)
+ params.push_back("+M");
+ else
+ params.push_back("-M");
+
+ if(half_size) params.push_back("-h");
+ if(dontstretch) params.push_back("-j");
+ if(camera_date) params.push_back("-z");
+ if(automatic_white) params.push_back("-a");
+ if(camera_white) params.push_back("-w");
+ if(document_mode) params.push_back("-d");
+ if(interpolate_rggb) params.push_back("-f");
+
+ char ss[32];
+
+ if(quick)
+ {
+ if(quick == 1)
+ quick = 0;
+
+ sprintf(ss, "%d", quick);
+ params.push_back("-q");
+ params.push_back(ss);
+ }
+
+ if(threshold != 99)
+ {
+ sprintf(ss, "%d", threshold);
+ params.push_back("-n");
+ params.push_back(ss);
+ }
+
+ if(black >= 0)
+ {
+ sprintf(ss, "%d", black);
+ params.push_back("-k");
+ params.push_back(ss);
+ }
+
+ sprintf(ss, "%d", different);
+ params.push_back("-s");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", brightness);
+ params.push_back("-b");
+ params.push_back(ss);
+
+ sprintf(ss, "%d", highlights);
+ params.push_back("-H");
+ params.push_back(ss);
+
+ if(flipping)
+ {
+ if(flipping == 1)
+ flipping = 0; // 0, 3, 5, 6 are accepted
+
+ sprintf(ss, "%d", flipping);
+ params.push_back("-t");
+ params.push_back(ss);
+ }
+
+#ifndef NO_LCMS
+ if(icc_cam)
+ {
+ params.push_back("-p");
+ params.push_back("embed");
+ }
+ else if(icc_file.length())
+ {
+ params.push_back("-p");
+ params.push_back(icc_file);
+ }
+#endif
+
+ const s32 argc = 9 + params.size();
+
+ const char *argv[argc];
+ argv[0] = KLDCRAW_S;
+
+ for(int i = 1;i < argc-8;i++)
+ argv[i] = params[i-1].c_str();
+
+ argv[argc-8] = "-c"; // write to stdout
+ argv[argc-7] = "--input";
+ argv[argc-6] = file.c_str();
+ argv[argc-5] = "--binary";
+ argv[argc-4] = KLDCRAW;
+ argv[argc-3] = "--output";
+ argv[argc-2] = tmp.c_str();
+ argv[argc-1] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(argv[0], (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DJVU
+
+ fmt_settings::iterator it = m_settings.find("scaledown");
+
+ // get aspect
+ s32 aspect = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(aspect < 1 || aspect > 12)
+ aspect = 2;
+
+ it = m_settings.find("page");
+
+ // get page number
+ s32 ipage = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 1 : (*it).second.iVal;
+
+ // correct
+ if(ipage < 0 || ipage > 1000)
+ ipage = 1;
+
+ int status;
+
+ s8 subsample[20];
+ s8 pagesp[20];
+
+ snprintf(subsample, 20, "-subsample=%d", aspect);
+ snprintf(pagesp, 20, "-page=%d", ipage);
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(DJVU, DJVU, "-format=ppm", subsample, pagesp, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_DXF
+
+ std::string tmmp = tmp + ".ppm";
+ fmt_settings::iterator it = m_settings.find("width");
+
+ // get aspect
+ s32 width = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(width < 0 || width > 10000)
+ width = 0;
+
+ it = m_settings.find("height");
+
+ // get page number
+ s32 height = (it == m_settings.end() || (*it).second.type != settings_value::v_int) ?
+ 0 : (*it).second.iVal;
+
+ // correct
+ if(height < 0 || height > 10000)
+ height = 0;
+
+ s32 status;
+
+ s8 swidth[20], sheight[20];
+
+ const int argc = 8;
+ const char *argv[argc];
+ const char *x = "-x", *y = "-y";
+
+ int i = 3;
+ argv[0] = VEC2WEB;
+ argv[1] = file.c_str();
+ argv[2] = tmmp.c_str();
+
+ if(width)
+ {
+ snprintf(swidth, 20, "%d", width);
+ argv[i++] = x;
+ argv[i++] = swidth;
+ }
+
+ if(height)
+ {
+ snprintf(sheight, 20, "%d", height);
+ argv[i++] = y;
+ argv[i++] = sheight;
+ }
+
+ argv[i] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(VEC2WEB, (char* const*)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmmp.c_str(), "rb");
+
+#elif defined CODEC_XCF
+
+ const s32 argc = 9;
+ int status;
+
+ fmt_settings::iterator it = m_settings.find("background");
+
+ // background for transparent images
+ std::string bkgr = (it == m_settings.end() || (*it).second.type != settings_value::v_string) ?
+ "#ffffff" : (*it).second.sVal;
+
+ it = m_settings.find("autocrop");
+
+ // autocrop ?
+ bool autocrop = (it == m_settings.end() || (*it).second.type != settings_value::v_bool) ?
+ false : (*it).second.bVal;
+
+ const char *argv[argc];
+ argv[0] = KLXCF2PNM;
+
+ std::string bg = "-b";
+ bg += bkgr;
+ argv[1] = bg.c_str();
+
+ int i = 2;
+
+ if(autocrop)
+ {
+ argv[i++] = "-C";
+ }
+
+ argv[i++] = "-T";
+ argv[i++] = "-c";
+ argv[i++] = "-o";
+ argv[i++] = tmp.c_str();
+ argv[i++] = file.c_str();
+ argv[i++] = (char *)0;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execvp(KLXCF2PNM, (char *const *)argv);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0); // TODO check for errors
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_NETPBM
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(NETPBM_S, NETPBM_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_LJPEG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(LJPEG2PPM_S, LJPEG2PPM_S, "--input", file.c_str(), "--binary", LJPEG2PPM, "--output", tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_FIG
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(XFIG_S, XFIG_S, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_TTF
+
+ int status;
+
+ pid_t pid = fork();
+
+ if(!pid)
+ {
+ execlp(TTF2PNM, TTF2PNM, file.c_str(), tmp.c_str(), (char *)0);
+ exit(1);
+ }
+ else if(pid == -1)
+ return SQE_R_BADFILE;
+
+ ::waitpid(pid, &status, 0);
+
+ if(WIFEXITED(status))
+ if(WEXITSTATUS(status))
+ return SQE_R_BADFILE;
+ else;
+ else
+ return SQE_R_BADFILE;
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#elif defined CODEC_EPS
+
+ /*
+ * EPS code was grabbed from KImageIO plugin for kdelibs-3.4.0. It is under LGPL.
+ */
+
+ FILE * ghostfd;
+ int x1, y1, x2, y2;
+
+ std::string cmdBuf;
+
+ size_t ps_offset, ps_size;
+
+ ifstreamK io;
+ io.open(file.c_str(), ios::in);
+
+ if(!io.good())
+ return SQE_R_NOFILE;
+
+ // find start of PostScript code
+ if (!seekToCodeStart(&io, ps_offset, ps_size))
+ return SQE_R_BADFILE;
+
+ // find bounding box
+ if(!bbox(&io, &x1, &y1, &x2, &y2))
+ return SQE_R_BADFILE;
+
+ x2 -= x1;
+ y2 -= y1;
+
+ double xScale = 1.0;
+ double yScale = 1.0;
+ bool needsScaling = false;
+ int wantedWidth = x2;
+ int wantedHeight = y2;
+
+ std::stringstream str(cmdBuf);
+
+ str << EPS2PPM << " -sOutputFile=";
+ str << tmp;
+ str << " -q -g";
+ str << wantedWidth << "x" << wantedHeight;
+ str << " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
+ "0 0 moveto "
+ "1000 0 lineto "
+ "1000 1000 lineto "
+ "0 1000 lineto "
+ "1 1 254 255 div setrgbcolor fill "
+ "0 0 0 setrgbcolor - -c showpage quit";
+
+ ghostfd = popen(str.str().c_str(), "w");
+
+ if(ghostfd == 0)
+ return SQE_R_BADFILE;
+
+ fprintf(ghostfd, "\n%d %d translate\n", int(-floorf(x1*xScale)), int(-floorf(y1*yScale)));
+
+ if(needsScaling)
+ fprintf(ghostfd, "%g %g scale\n", xScale, yScale);
+
+ io.seekg(0, ios::beg);
+
+ char bbuf[4096];
+
+ if(ps_offset > 0) // We have an offset
+ io.seekg(ps_offset, ios::beg);
+
+ std::string buffer;
+
+ while(!io.eof())
+ {
+ io.read(bbuf, sizeof(bbuf));
+ buffer.append(bbuf, io.gcount());
+ }
+
+ // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
+ if (ps_size <= 0 || ps_size > buffer.size())
+ ps_size = buffer.size();
+
+ fwrite(buffer.c_str(), sizeof(char), ps_size, ghostfd);
+
+ pclose(ghostfd);
+
+ fptr = fopen(tmp.c_str(), "rb");
+
+#else
+
+ fptr = fopen(file.c_str(), "rb");
+
+#endif
+
+ if(!fptr)
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ s8 str[256];
+ s32 w, h;
+ u32 maxcolor;
+
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ pnm = str[1] - 48;
+
+ if(pnm < 1 || pnm > 6)
+ return SQE_R_BADFILE;
+
+ while(true)
+ {
+ if(!sq_fgets(str, 255, fptr)) return SQE_R_BADFILE;
+
+ if(str[0] != '#')
+ break;
+ }
+
+ sscanf(str, "%d%d", &w, &h);
+
+ image.w = w;
+ image.h = h;
+
+ switch(pnm)
+ {
+ case 1:
+ case 4:
+ image.bpp = 1;
+ break;
+
+ case 2:
+ case 5:
+ image.bpp = 8;
+ break;
+
+ case 3:
+ case 6:
+ image.bpp = 8;
+ break;
+ }
+
+ if(pnm != 4 && pnm != 1)
+ {
+ fscanf(fptr, "%d", &maxcolor);
+
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ if((pnm == 5 || pnm == 6) && maxcolor > 255)
+ return SQE_R_BADFILE;
+
+ if(pnm == 2 || pnm == 3)
+ {
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ else
+ {
+ u8 dummy;
+ if(!sq_fgetc(fptr, &dummy)) return SQE_R_BADFILE;
+ }
+
+ if(maxcolor <= 9)
+ strcpy(format, "%1d");
+ else if(maxcolor >= 9 && maxcolor <= 99)
+ strcpy(format, "%2d");
+ else if(maxcolor > 99 && maxcolor <= 999)
+ strcpy(format, "%3d");
+ else if(maxcolor > 999 && maxcolor <= 9999)
+ strcpy(format, "%4d");
+
+ koeff = 255.0 / maxcolor;
+ }
+ else if(pnm == 1)
+ {
+ strcpy(format, "%1d");
+ koeff = 1.0;
+ }
+
+ image.compression = "-";
+ image.colorspace = ((pnm == 1 || pnm == 4) ? "Monochrome":"Color indexed");
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ u8 bt;
+ s32 i, a;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ switch(pnm)
+ {
+ case 1:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memcpy(scan+i, palmono+a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 2:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a);
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ a = (s32)(a * koeff);
+
+ memset(scan+i, a, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ }
+ break;
+
+ case 3:
+ for(i = 0;i < im->w;i++)
+ {
+ fscanf(fptr, format, &a); rgb.r = a;
+ fscanf(fptr, format, &a); rgb.g = a;
+ fscanf(fptr, format, &a); rgb.b = a;
+ if(sq_ferror(fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ if(!skip_flood(fptr))
+ return SQE_R_BADFILE;
+ break;
+
+ case 6:
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&rgb, sizeof(RGB), 1, fptr)) return SQE_R_BADFILE;
+
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+ break;
+
+ case 5:
+ {
+ for(i = 0;i < im->w;i++)
+ {
+ if(!sq_fread(&bt, 1, 1, fptr)) return SQE_R_BADFILE;
+
+ memset(scan+i, int(bt*koeff), sizeof(RGB));
+ }
+ }
+ break;
+
+ case 4:
+ {
+ s32 index;//, remain = im->w % 8;
+
+ for(i = 0;;)
+ {
+ if(!sq_fread(&bt,1,1,fptr)) return SQE_R_BADFILE;
+
+ index = (bt&128)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&64)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&32)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&16)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&8)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&4)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&2)?1:0;
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ index = (bt&1);
+ memcpy(scan+i, palmono+index, 3);i++; if(i >= im->w) break;
+ }
+ }
+ break;
+ }
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ if(fptr)
+ fclose(fptr);
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+bool skip_flood(FILE *f)
+{
+ s32 pos;
+ u8 b;
+
+ while(true)
+ {
+ pos = ftell(f);
+ if(!sq_fread(&b, 1, 1, f)) return false;
+
+ if(!isspace(b))
+ {
+ if(b == '#')
+ {
+ while(true)
+ {
+ if(!sq_fgetc(f, &b)) return false;
+
+ if(b == '\n')
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ fsetpos(f, (fpos_t*)&pos);
+
+ return true;
+}
+
+#ifdef CODEC_PNM
+
+void fmt_codec::getwriteoptions(fmt_writeoptionsabs *opt)
+{
+ opt->interlaced = false;
+ opt->compression_scheme = CompressionNo;
+ opt->compression_min = 0;
+ opt->compression_max = 0;
+ opt->compression_def = 0;
+ opt->passes = 1;
+ opt->needflip = false;
+ opt->palette_flags = 0 | fmt_image::pure32;
+}
+
+s32 fmt_codec::write_init(const std::string &file, const fmt_image &image, const fmt_writeoptions &opt)
+{
+ if(!image.w || !image.h || file.empty())
+ return SQE_W_WRONGPARAMS;
+
+ writeimage = image;
+ writeopt = opt;
+
+ fws.open(file.c_str(), ios::binary | ios::out);
+
+ if(!fws.good())
+ return SQE_W_NOFILE;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_next()
+{
+ fws << "P6" << endl << writeimage.w << " " << writeimage.h << endl << 255 << endl;
+
+ return fws.good() ? SQE_OK : SQE_W_ERROR;
+}
+
+s32 fmt_codec::write_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::write_scanline(RGBA *scan)
+{
+ for(s32 i = 0;i < writeimage.w;i++)
+ {
+ if(!fws.writeK(scan+i, sizeof(RGB)))
+ return SQE_W_ERROR;
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::write_close()
+{
+ fws.close();
+}
+
+std::string fmt_codec::extension(const s32 /*bpp*/)
+{
+ return std::string("pnm");
+}
+
+#endif // CODEC_PNM
+
+#include "fmt_codec_cd_func.h"