summaryrefslogtreecommitdiffstats
path: root/kernel/kls_ljpeg
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
commit0292059f4a16434600564cfa3f0ad2309a508a54 (patch)
treed95953cd53011917c4df679b96aedca39401b54f /kernel/kls_ljpeg
downloadlibksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.tar.gz
libksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.zip
Added libksquirrel for KDE3
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/libraries/libksquirrel@1095624 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kernel/kls_ljpeg')
-rw-r--r--kernel/kls_ljpeg/Makefile.am17
-rw-r--r--kernel/kls_ljpeg/fmt_codec_pnm.cpp1470
-rw-r--r--kernel/kls_ljpeg/fmt_codec_pnm_defs.h64
-rw-r--r--kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in18
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/Copyright79
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/Makefile.am5
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/huffd.c665
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/io.h105
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/jpeg.h249
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c263
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/mcu.c125
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/mcu.h63
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/predictor.c189
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/predictor.h176
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/proto.h75
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/read.c665
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/util.c297
17 files changed, 4525 insertions, 0 deletions
diff --git a/kernel/kls_ljpeg/Makefile.am b/kernel/kls_ljpeg/Makefile.am
new file mode 100644
index 0000000..e2f720d
--- /dev/null
+++ b/kernel/kls_ljpeg/Makefile.am
@@ -0,0 +1,17 @@
+SUBDIRS = ljpeg2ppm
+
+INCLUDES = -I../include
+
+bin_SCRIPTS = ksquirrel-libs-ljpeg2ppm-s
+
+pkglib_LTLIBRARIES = libkls_ljpeg.la
+
+libkls_ljpeg_la_SOURCES = fmt_codec_pnm.cpp fmt_codec_pnm_defs.h
+
+libkls_ljpeg_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_ljpeg_la_LIBADD = ${SQ_LOCAL_RPATH}
+
+AM_CXXFLAGS = -DCODEC_LJPEG -DLJPEG2PPM_S=\"${bindir}/ksquirrel-libs-ljpeg2ppm-s\" -DLJPEG2PPM=\"${bindir}/ksquirrel-libs-ljpeg2ppm\"
+
+EXTRA_DIST = ksquirrel-libs-ljpeg2ppm-s.in
diff --git a/kernel/kls_ljpeg/fmt_codec_pnm.cpp b/kernel/kls_ljpeg/fmt_codec_pnm.cpp
new file mode 100644
index 0000000..06aedd6
--- /dev/null
+++ b/kernel/kls_ljpeg/fmt_codec_pnm.cpp
@@ -0,0 +1,1470 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <[email protected]>
+
+ 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"
diff --git a/kernel/kls_ljpeg/fmt_codec_pnm_defs.h b/kernel/kls_ljpeg/fmt_codec_pnm_defs.h
new file mode 100644
index 0000000..bc61ec4
--- /dev/null
+++ b/kernel/kls_ljpeg/fmt_codec_pnm_defs.h
@@ -0,0 +1,64 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2004 Dmitry Baryshev <[email protected]>
+
+ 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.
+*/
+
+#ifndef KSQUIRREL_READ_IMAGE_pnm
+#define KSQUIRREL_READ_IMAGE_pnm
+
+bool skip_flood(FILE *);
+
+bool sq_fgetc(FILE *f, u8 *c)
+{
+ s32 e = fgetc(f);
+
+ if(ferror(f) || feof(f))
+ return false;
+
+ *c = e;
+
+ return true;
+}
+
+bool sq_fgets(s8 *s, s32 size, FILE *stream)
+{
+ s8 *r = (s8*)fgets((char*)s, size, stream);
+
+ if(ferror(stream) || feof(stream) || !r)
+ return false;
+
+ return true;
+}
+
+bool sq_ferror(FILE *f)
+{
+ return (ferror(f) || feof(f));
+}
+
+bool sq_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t r = fread(ptr, size, nmemb, stream);
+
+ if(ferror(stream) || feof(stream) || r != nmemb)
+ return false;
+
+ return true;
+}
+
+#endif
diff --git a/kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in b/kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in
new file mode 100644
index 0000000..74c3038
--- /dev/null
+++ b/kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+kls_ljpeg_i=""
+kls_ljpeg_o=""
+kls_ljpeg_bin=""
+
+while [ "$1" ] ; do
+
+ case "$1" in
+ "--input") kls_ljpeg_i="$2" shift ;;
+ "--output") kls_ljpeg_o="$2" shift ;;
+ "--binary") kls_ljpeg_bin="$2" shift ;;
+ esac
+
+shift
+done
+
+$kls_ljpeg_bin "$kls_ljpeg_i" > "$kls_ljpeg_o" \ No newline at end of file
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/Copyright b/kernel/kls_ljpeg/ljpeg2ppm/Copyright
new file mode 100644
index 0000000..5fae625
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/Copyright
@@ -0,0 +1,79 @@
+Copyright (c) 1993 Cornell University, Kongji Huang
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for research purposes, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+
+Copyright (c) 1993 The Regents of the University of California, Brian
+C. Smith All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+IJG Copyright
+
+The authors make NO WARRANTY or representation, either express or
+implied, with respect to this software, its quality, accuracy,
+merchantability, or fitness for a particular purpose. This software is
+provided "AS IS", and you, its user, assume the entire risk as to its
+quality and accuracy.
+
+This software is copyright (C) 1991, 1992, Thomas G. Lane. All Rights
+Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to
+these conditions: (1) If any part of the source code for this software
+is distributed, then this README file must be included, with this
+copyright and no-warranty notice unaltered; and any additions,
+deletions, or changes to the original files must be clearly indicated
+in accompanying documentation. (2) If only executable code is
+distributed, then the accompanying documentation must state that "this
+software is based in part on the work of the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user
+accepts full responsibility for any undesirable consequences; the
+authors accept NO LIABILITY for damages of any kind.
+
+Permission is NOT granted for the use of any IJG author's name or
+company name in advertising or publicity relating to this software or
+products derived from it. This software may be referred to only as
+"the Independent JPEG Group's software".
+
+We specifically permit and encourage the use of this software as the
+basis of commercial products, provided that all warranty or liability
+claims are assumed by the product vendor.
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am b/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am
new file mode 100644
index 0000000..8d9632e
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am
@@ -0,0 +1,5 @@
+#INCLUDES = -I../include
+
+bin_PROGRAMS = ksquirrel-libs-ljpeg2ppm
+
+ksquirrel_libs_ljpeg2ppm_SOURCES = huffd.c io.h jpeg.h ljpgtopnm.c mcu.c mcu.h predictor.c predictor.h proto.h read.c util.c
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/huffd.c b/kernel/kls_ljpeg/ljpeg2ppm/huffd.c
new file mode 100644
index 0000000..da5d2e9
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/huffd.c
@@ -0,0 +1,665 @@
+/*
+ * huffd.c --
+ *
+ * Code for JPEG lossless decoding. Large parts are grabbed from the IJG
+ * software, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "io.h"
+#include "proto.h"
+#include "predictor.h"
+
+#define RST0 0xD0 /* RST0 marker code */
+
+static long getBuffer; /* current bit-extraction buffer */
+static int bitsLeft; /* # of unused bits in it */
+
+/*
+ * The following variables keep track of the input buffer
+ * for the JPEG data, which is read by ReadJpegData.
+ */
+Uchar inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
+int numInputBytes; /* The total number of bytes in inputBuffer */
+int maxInputBytes; /* Size of inputBuffer */
+int inputBufferOffset; /* Offset of current byte */
+
+/*
+ * Code for extracting the next N bits from the input stream.
+ * (N never exceeds 15 for JPEG data.)
+ * This needs to go as fast as possible!
+ *
+ * We read source bytes into getBuffer and dole out bits as needed.
+ * If getBuffer already contains enough bits, they are fetched in-line
+ * by the macros get_bits() and get_bit(). When there aren't enough bits,
+ * FillBitBuffer is called; it will attempt to fill getBuffer to the
+ * "high water mark", then extract the desired number of bits. The idea,
+ * of course, is to minimize the function-call overhead cost of entering
+ * FillBitBuffer.
+ * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
+ * of getBuffer to be used. (On machines with wider words, an even larger
+ * buffer could be used.)
+ */
+
+#define BITS_PER_LONG (8*sizeof(long))
+#define MIN_GET_BITS (BITS_PER_LONG-7) /* max value for long getBuffer */
+
+/*
+ * bmask[n] is mask for n rightmost bits
+ */
+static int bmask[] = {0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000F,
+ 0x001F, 0x003F, 0x007F, 0x00FF,
+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
+ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FillBitBuffer --
+ *
+ * Load up the bit buffer with at least nbits
+ * Process any stuffed bytes at this time.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The bitwise global variables are updated.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+FillBitBuffer (nbits)
+ int nbits;
+{
+ int c, c2;
+
+ while (bitsLeft < MIN_GET_BITS) {
+ c = GetJpegChar ();
+
+ /*
+ * If it's 0xFF, check and discard stuffed zero byte
+ */
+ if (c == 0xFF) {
+ c2 = GetJpegChar ();
+
+ if (c2 != 0) {
+
+ /*
+ * Oops, it's actually a marker indicating end of
+ * compressed data. Better put it back for use later.
+ */
+ UnGetJpegChar (c2);
+ UnGetJpegChar (c);
+
+ /*
+ * There should be enough bits still left in the data
+ * segment; if so, just break out of the while loop.
+ */
+ if (bitsLeft >= nbits)
+ break;
+
+ /*
+ * Uh-oh. Corrupted data: stuff zeroes into the data
+ * stream, since this sometimes occurs when we are on the
+ * last show_bits(8) during decoding of the Huffman
+ * segment.
+ */
+ c = 0;
+ }
+ }
+ /*
+ * OK, load c into getBuffer
+ */
+ getBuffer = (getBuffer << 8) | c;
+ bitsLeft += 8;
+ }
+}
+
+/* Macros to make things go at some speed! */
+/* NB: parameter to get_bits should be simple variable, not expression */
+
+#define show_bits(nbits,rv) { \
+ if (bitsLeft < nbits) FillBitBuffer(nbits); \
+ rv = (getBuffer >> (bitsLeft-(nbits))) & bmask[nbits]; \
+}
+
+#define show_bits8(rv) { \
+ if (bitsLeft < 8) FillBitBuffer(8); \
+ rv = (getBuffer >> (bitsLeft-8)) & 0xff; \
+}
+
+#define flush_bits(nbits) { \
+ bitsLeft -= (nbits); \
+}
+
+#define get_bits(nbits,rv) { \
+ if (bitsLeft < nbits) FillBitBuffer(nbits); \
+ rv = ((getBuffer >> (bitsLeft -= (nbits)))) & bmask[nbits]; \
+}
+
+#define get_bit(rv) { \
+ if (!bitsLeft) FillBitBuffer(1); \
+ rv = (getBuffer >> (--bitsLeft)) & 1; \
+}
+
+#ifdef DEBUG
+/*
+ *--------------------------------------------------------------
+ *
+ * PmPutRow --
+ *
+ * Output one row of pixels stored in RowBuf.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * One row of pixels are write to file pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+PmPutRow(RowBuf,numComp,numCol,Pt)
+ MCU *RowBuf;
+ int numCol,Pt;
+{
+ register int col,v;
+
+ /*
+ * Mulitply 2^Pt before output. Pt is the point
+ * transform parameter.
+ */
+ if (numComp==1) { /*pgm*/
+ for (col = 0; col < numCol; col++) {
+ v=RowBuf[col][0]<<Pt;
+ (void)putc(v,outFile);
+ }
+ } else { /*ppm*/
+ for (col = 0; col < numCol; col++) {
+ v=RowBuf[col][0]<<Pt;
+ (void)putc(v,outFile);
+ v=RowBuf[col][1]<<Pt;
+ (void)putc(v,outFile);
+ v=RowBuf[col][2]<<Pt;
+ (void)putc(v,outFile);
+ }
+ }
+}
+#else
+/*
+ *--------------------------------------------------------------
+ *
+ * PmPutRow --
+ *
+ * Output one row of pixels stored in RowBuf.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * One row of pixels are write to file pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+#define PmPutRow(RowBuf,numComp,numCol,Pt) \
+{ register int col,v; \
+ if (numComp==1) { /*pgm*/ \
+ for (col = 0; col < numCol; col++) { \
+ v=RowBuf[col][0]<<Pt; \
+ (void)putc(v,outFile); \
+ } \
+ } else { /*ppm*/ \
+ for (col = 0; col < numCol; col++) { \
+ v=RowBuf[col][0]<<Pt; \
+ (void)putc(v,outFile); \
+ v=RowBuf[col][1]<<Pt; \
+ (void)putc(v,outFile); \
+ v=RowBuf[col][2]<<Pt; \
+ (void)putc(v,outFile); \
+ } \
+ } \
+}
+#endif
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffDecode --
+ *
+ * Taken from Figure F.16: extract next coded symbol from
+ * input stream. This should becode a macro.
+ *
+ * Results:
+ * Next coded symbol
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+#define HuffDecode(htbl,rv) \
+{ \
+ int l, code, temp; \
+ \
+ /* \
+ * If the huffman code is less than 8 bits, we can use the fast \
+ * table lookup to get its value. It's more than 8 bits about \
+ * 3-4% of the time. \
+ */ \
+ show_bits8(code); \
+ if (htbl->numbits[code]) { \
+ flush_bits(htbl->numbits[code]); \
+ rv=htbl->value[code]; \
+ } else { \
+ flush_bits(8); \
+ l = 8; \
+ while (code > htbl->maxcode[l]) { \
+ get_bit(temp); \
+ code = (code << 1) | temp; \
+ l++; \
+ } \
+ \
+ /* \
+ * With garbage input we may reach the sentinel value l = 17. \
+ */ \
+ \
+ if (l > 16) { \
+ fprintf (stderr, "Corrupt JPEG data: bad Huffman code"); \
+ rv = 0; /* fake a zero as the safest result */ \
+ } else { \
+ rv = htbl->huffval[htbl->valptr[l] + \
+ ((int)(code - htbl->mincode[l]))]; \
+ } \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffExtend --
+ *
+ * Code and table for Figure F.12: extend sign bit
+ *
+ * Results:
+ * The extended value.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+static int extendTest[16] = /* entry n is 2**(n-1) */
+{0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
+
+static int extendOffset[16] = /* entry n is (-1 << n) + 1 */
+{0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
+ ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
+ ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
+ ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
+
+#define HuffExtend(x,s) { \
+ if ((x) < extendTest[s]) { \
+ (x) += extendOffset[s]; \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffDecoderInit --
+ *
+ * Initialize for a Huffman-compressed scan.
+ * This is invoked after reading the SOS marker.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+HuffDecoderInit (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ short ci;
+ JpegComponentInfo *compptr;
+
+ /*
+ * Initialize static variables
+ */
+ bitsLeft = 0;
+
+ for (ci = 0; ci < dcPtr->compsInScan; ci++) {
+ compptr = dcPtr->curCompInfo[ci];
+ /*
+ * Make sure requested tables are present
+ */
+ if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
+ fprintf (stderr, "Error: Use of undefined Huffman table\n");
+ exit (1);
+ }
+
+ /*
+ * Compute derived values for Huffman tables.
+ * We may do this more than once for same table, but it's not a
+ * big deal
+ */
+ FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
+ }
+
+ /*
+ * Initialize restart stuff
+ */
+ dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
+ dcPtr->restartRowsToGo = dcPtr->restartInRows;
+ dcPtr->nextRestartNum = 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ProcessRestart --
+ *
+ * Check for a restart marker & resynchronize decoder.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * BitStream is parsed, bit buffer is reset, etc.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+ProcessRestart (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, nbytes;
+ short ci;
+
+ /*
+ * Throw away any unused bits remaining in bit buffer
+ */
+ nbytes = bitsLeft / 8;
+ bitsLeft = 0;
+
+ /*
+ * Scan for next JPEG marker
+ */
+ do {
+ do { /* skip any non-FF bytes */
+ nbytes++;
+ c = GetJpegChar ();
+ } while (c != 0xFF);
+ do { /* skip any duplicate FFs */
+ /*
+ * we don't increment nbytes here since extra FFs are legal
+ */
+ c = GetJpegChar ();
+ } while (c == 0xFF);
+ } while (c == 0); /* repeat if it was a stuffed FF/00 */
+
+ if (c != (RST0 + dcPtr->nextRestartNum)) {
+
+ /*
+ * Uh-oh, the restart markers have been messed up too.
+ * Just bail out.
+ */
+ fprintf (stderr, "Error: Corrupt JPEG data. Exiting...\n");
+ exit(-1);
+ }
+
+ /*
+ * Update restart state
+ */
+ dcPtr->restartRowsToGo = dcPtr->restartInRows;
+ dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeFirstRow --
+ *
+ * Decode the first raster line of samples at the start of
+ * the scan and at the beginning of each restart interval.
+ * This includes modifying the component value so the real
+ * value, not the difference is returned.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void DecodeFirstRow(dcPtr,curRowBuf)
+ DecompressInfo *dcPtr;
+ MCU *curRowBuf;
+{
+ register short curComp,ci;
+ register int s,col,compsInScan,numCOL;
+ register JpegComponentInfo *compptr;
+ int Pr,Pt,d;
+ HuffmanTable *dctbl;
+
+ Pr=dcPtr->dataPrecision;
+ Pt=dcPtr->Pt;
+ compsInScan=dcPtr->compsInScan;
+ numCOL=dcPtr->imageWidth;
+
+ /*
+ * the start of the scan or at the beginning of restart interval.
+ */
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ /*
+ * Add the predictor to the difference.
+ */
+ curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
+ }
+
+ /*
+ * the rest of the first row
+ */
+ for (col=1; col<numCOL; col++) {
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ /*
+ * Add the predictor to the difference.
+ */
+ curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
+ }
+ }
+
+ if (dcPtr->restartInRows) {
+ (dcPtr->restartRowsToGo)--;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeImage --
+ *
+ * Decode the input stream. This includes modifying
+ * the component value so the real value, not the
+ * difference is returned.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void
+DecodeImage(dcPtr)
+ DecompressInfo *dcPtr;
+{
+ register int s,d,col,row;
+ register short curComp, ci;
+ HuffmanTable *dctbl;
+ JpegComponentInfo *compptr;
+ int predictor;
+ int numCOL,numROW,compsInScan;
+ MCU *prevRowBuf,*curRowBuf;
+ int imagewidth,Pt,psv;
+
+ numCOL=imagewidth=dcPtr->imageWidth;
+ numROW=dcPtr->imageHeight;
+ compsInScan=dcPtr->compsInScan;
+ Pt=dcPtr->Pt;
+ psv=dcPtr->Ss;
+ prevRowBuf=mcuROW2;
+ curRowBuf=mcuROW1;
+
+ /*
+ * Decode the first row of image. Output the row and
+ * turn this row into a previous row for later predictor
+ * calculation.
+ */
+ DecodeFirstRow(dcPtr,curRowBuf);
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+
+ for (row=1; row<numROW; row++) {
+
+ /*
+ * Account for restart interval, process restart marker if needed.
+ */
+ if (dcPtr->restartInRows) {
+ if (dcPtr->restartRowsToGo == 0) {
+ ProcessRestart (dcPtr);
+
+ /*
+ * Reset predictors at restart.
+ */
+ DecodeFirstRow(dcPtr,curRowBuf);
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+ continue;
+ }
+ dcPtr->restartRowsToGo--;
+ }
+
+ /*
+ * The upper neighbors are predictors for the first column.
+ */
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
+ }
+
+ /*
+ * For the rest of the column on this row, predictor
+ * calculations are base on PSV.
+ */
+ for (col=1; col<numCOL; col++) {
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+ QuickPredict(col,curComp,curRowBuf,prevRowBuf,
+ psv,&predictor);
+
+ curRowBuf[col][curComp]=d+predictor;
+ }
+ }
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+ }
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/io.h b/kernel/kls_ljpeg/ljpeg2ppm/io.h
new file mode 100644
index 0000000..65d9636
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/io.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _IO
+#define _IO
+
+/*
+ * Size of the input and output buffer
+ */
+#define JPEG_BUF_SIZE 4096
+
+/*
+ * The following variables keep track of the input and output
+ * buffer for the JPEG data.
+ */
+extern char outputBuffer[JPEG_BUF_SIZE]; /* output buffer */
+extern int numOutputBytes; /* bytes in the output buffer */
+extern Uchar inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
+extern int numInputBytes; /* bytes in inputBuffer */
+extern int maxInputBytes; /* Size of inputBuffer */
+extern int inputBufferOffset; /* Offset of current byte */
+
+/*
+ * the output file pointer.
+ */
+extern FILE *outFile;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * EmitByte --
+ *
+ * Write a single byte out to the output buffer, and
+ * flush if it's full.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The outp[ut buffer may get flushed.
+ *
+ *--------------------------------------------------------------
+ */
+#define EmitByte(val) { \
+ if (numOutputBytes >= JPEG_BUF_SIZE) { \
+ FlushBytes(); \
+ } \
+ outputBuffer[numOutputBytes++] = (char)(val); \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetJpegChar, UnGetJpegChar --
+ *
+ * Macros to get the next character from the input stream.
+ *
+ * Results:
+ * GetJpegChar returns the next character in the stream, or EOF
+ * UnGetJpegChar returns nothing.
+ *
+ * Side effects:
+ * A byte is consumed or put back into the inputBuffer.
+ *
+ *--------------------------------------------------------------
+ */
+#define GetJpegChar() \
+ ((inputBufferOffset < numInputBytes)? \
+ inputBuffer[inputBufferOffset++]: \
+ (numInputBytes = 2+ReadJpegData(inputBuffer+2,JPEG_BUF_SIZE-2), \
+ inputBufferOffset = 2, \
+ ((inputBufferOffset < numInputBytes)? \
+ inputBuffer[inputBufferOffset++]: \
+ EOF)))
+
+#define UnGetJpegChar(ch) (inputBuffer[--inputBufferOffset]=(ch))
+
+#endif /* _IO */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h b/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h
new file mode 100644
index 0000000..44a41cb
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h
@@ -0,0 +1,249 @@
+/*
+ * jpeg.h --
+ *
+ * Basic jpeg data structure definitions.
+ *
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _JPEG
+#define _JPEG
+
+typedef unsigned char Uchar;
+typedef unsigned short Ushort;
+typedef unsigned int Uint;
+
+/*
+ * The following structure stores basic information about one component.
+ */
+typedef struct JpegComponentInfo {
+ /*
+ * These values are fixed over the whole image.
+ * They are read from the SOF marker.
+ */
+ short componentId; /* identifier for this component (0..255) */
+ short componentIndex; /* its index in SOF or cPtr->compInfo[] */
+
+ /*
+ * Downsampling is not normally used in lossless JPEG, although
+ * it is permitted by the JPEG standard (DIS). We set all sampling
+ * factors to 1 in this program.
+ */
+ short hSampFactor; /* horizontal sampling factor */
+ short vSampFactor; /* vertical sampling factor */
+
+ /*
+ * Huffman table selector (0..3). The value may vary
+ * between scans. It is read from the SOS marker.
+ */
+ short dcTblNo;
+} JpegComponentInfo;
+
+
+/*
+ * One of the following structures is created for each huffman coding
+ * table. We use the same structure for encoding and decoding, so there
+ * may be some extra fields for encoding that aren't used in the decoding
+ * and vice-versa.
+ */
+typedef struct HuffmanTable {
+ /*
+ * These two fields directly represent the contents of a JPEG DHT
+ * marker
+ */
+ Uchar bits[17];
+ Uchar huffval[256];
+
+ /*
+ * This field is used only during compression. It's initialized
+ * FALSE when the table is created, and set TRUE when it's been
+ * output to the file.
+ */
+ int sentTable;
+
+ /*
+ * The remaining fields are computed from the above to allow more
+ * efficient coding and decoding. These fields should be considered
+ * private to the Huffman compression & decompression modules.
+ */
+ Ushort ehufco[256];
+ char ehufsi[256];
+
+ Ushort mincode[17];
+ int maxcode[18];
+ short valptr[17];
+ int numbits[256];
+ int value[256];
+} HuffmanTable;
+
+/*
+ * One of the following structures is used to pass around the
+ * compression information.
+ */
+typedef struct CompressInfo {
+ /*
+ * Image width, height, and image data precision (bits/sample)
+ */
+ int imageWidth;
+ int imageHeight;
+ int dataPrecision;
+
+ /*
+ * compInfo[i] describes component that appears i'th in SOF
+ * numComponents is the # of color components in JPEG image.
+ */
+ JpegComponentInfo *compInfo;
+ short numComponents;
+
+ /*
+ * *curCompInfo[i] describes component that appears i'th in SOS.
+ * compsInScan is the # of color components in current scan.
+ */
+ JpegComponentInfo *curCompInfo[4];
+ short compsInScan;
+
+ /*
+ * MCUmembership[i] indexes the i'th component of MCU into the
+ * curCompInfo array.
+ */
+ short MCUmembership[10];
+
+ /*
+ * Pointers to Huffman coding tables, or NULL if not defined.
+ */
+ HuffmanTable *dcHuffTblPtrs[4];
+
+ /*
+ * prediction seletion value (PSV) and point transform parameter (Pt)
+ */
+ int Ss;
+ int Pt;
+
+ /*
+ * In lossless JPEG, restart interval shall be an integer
+ * multiple of the number of MCU in a MCU row.
+ */
+ int restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
+
+ /*
+ * These fields are private data for the entropy encoder
+ */
+ int restartRowsToGo; /* MCUs rows left in this restart interval */
+ short nextRestartNum; /* # of next RSTn marker (0..7) */
+} CompressInfo;
+
+/*
+ * One of the following structures is used to pass around the
+ * decompression information.
+ */
+typedef struct DecompressInfo {
+ /*
+ * Image width, height, and image data precision (bits/sample)
+ * These fields are set by ReadFileHeader or ReadScanHeader
+ */
+ int imageWidth;
+ int imageHeight;
+ int dataPrecision;
+
+ /*
+ * compInfo[i] describes component that appears i'th in SOF
+ * numComponents is the # of color components in JPEG image.
+ */
+ JpegComponentInfo *compInfo;
+ short numComponents;
+
+ /*
+ * *curCompInfo[i] describes component that appears i'th in SOS.
+ * compsInScan is the # of color components in current scan.
+ */
+ JpegComponentInfo *curCompInfo[4];
+ short compsInScan;
+
+ /*
+ * MCUmembership[i] indexes the i'th component of MCU into the
+ * curCompInfo array.
+ */
+ short MCUmembership[10];
+
+ /*
+ * ptrs to Huffman coding tables, or NULL if not defined
+ */
+ HuffmanTable *dcHuffTblPtrs[4];
+
+ /*
+ * prediction seletion value (PSV) and point transform parameter (Pt)
+ */
+ int Ss;
+ int Pt;
+
+ /*
+ * In lossless JPEG, restart interval shall be an integer
+ * multiple of the number of MCU in a MCU row.
+ */
+ int restartInterval;/* MCUs per restart interval, 0 = no restart */
+ int restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
+
+ /*
+ * these fields are private data for the entropy decoder
+ */
+ int restartRowsToGo; /* MCUs rows left in this restart interval */
+ short nextRestartNum; /* # of next RSTn marker (0..7) */
+} DecompressInfo;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * swap --
+ *
+ * Swap the contents stored in a and b.
+ * "type" is the variable type of a and b.
+ *
+ * Results:
+ * The values in a and b are swapped.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define swap(type,a,b) {type c; c=(a); (a)=(b); (b)=c;}
+
+#define MEMSET(s,c,n) memset((void *)(s),(int)(c),(int)(n))
+#define MEMCPY(s1,s2,n) memcpy((void *)(s1),(void *)(s2),(int)(n))
+
+/*
+ * Lossless JPEG specifies data precision to be from 2 to 16 bits/sample.
+ */
+#define MinPrecisionBits 2
+#define MaxPrecisionBits 16
+#define MinPrecisionValue 2
+#define MaxPrecisionValue 65535
+
+#endif /* _JPEG */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c b/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c
new file mode 100644
index 0000000..c975892
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c
@@ -0,0 +1,263 @@
+/*
+ * ljpgtopnm.c --
+ *
+ * This is the main routine for the lossless JPEG decoder. Large
+ * parts are stolen from the IJG code, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+/*
+ * input and output file pointers
+ */
+FILE *inFile, *outFile;
+void FreeArray2D(char **);
+
+void WritePmHeader(DecompressInfo dcInfo);
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadJpegData --
+ *
+ * This is an interface routine to the JPEG library. The
+ * JPEG library calls this routine to "get more data"
+ *
+ * Results:
+ * Number of bytes actually returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+int
+ReadJpegData (buffer, numBytes)
+ char *buffer; /* Place to put new data */
+ int numBytes; /* Number of bytes to put */
+{
+ return fread(buffer, 1, numBytes, inFile);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * WritePmHeader --
+ *
+ * Output Portable Pixmap (PPM) or Portable
+ * Graymap (PGM) image header.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The PPM or PGM header is written to file
+ * pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+void
+WritePmHeader(dcInfo)
+DecompressInfo dcInfo;
+{
+ switch(dcInfo.numComponents) {
+ case 1: /* pgm */
+ if (dcInfo.dataPrecision==8) {
+ fprintf(outFile,"P5\n%d %d\n255\n",
+ dcInfo.imageWidth,dcInfo.imageHeight);
+ } else {
+ fprintf(outFile,"P5\n%d %d\n%d\n",
+ dcInfo.imageWidth,dcInfo.imageHeight,
+ ((1<<dcInfo.dataPrecision)-1));
+ }
+ break;
+ case 3: /* ppm */
+ if (dcInfo.dataPrecision==8) {
+ fprintf(outFile,"P6\n%d %d\n255\n",
+ dcInfo.imageWidth,dcInfo.imageHeight);
+ } else {
+ fprintf(outFile,"P6\n%d %d\n%d\n",
+ dcInfo.imageWidth,dcInfo.imageHeight,
+ ((1<<dcInfo.dataPrecision)-1));
+ }
+ break;
+ default:
+ fprintf(stderr,"Error: Unsupported image format.\n");
+ exit(-1);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ArgParser --
+ *
+ * Command line parser.
+ *
+ * Results:
+ * Command line parameters and options are passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+ArgParser(argc,argv,verbose,linFile,loutFile)
+ int argc;
+ char **argv;
+ int *verbose;
+ FILE **linFile, **loutFile;
+{
+ int argn;
+ char *arg;
+ const char *usage="ppmtoljpeg [ -v -h ] [ inFile [outFile] ]";
+ int NumOfFile=0;
+
+ /*
+ * default values
+ */
+ *linFile=stdin;
+ *loutFile=stdout;
+ *verbose=0;
+
+ for (argn = 1; argn < argc; argn++) {
+ arg=argv[argn];
+ if (*arg != '-') { /* process a file name */
+ if (NumOfFile==0) {
+ if ((*linFile=fopen(arg,"r"))==NULL) {
+ fprintf(stderr,"Can't open %s\n",arg);
+ exit(-1);
+ }
+ }
+ if (NumOfFile==1) {
+ if ((*loutFile=fopen(arg,"w"))==NULL) {
+ fprintf(stderr,"Can't open %s\n",arg);
+ exit(-1);
+ }
+ }
+ if (NumOfFile>1) {
+ fprintf(stderr,"%s\n",usage);
+ exit(-1);
+ }
+ NumOfFile++;
+ }
+ else { /* precess a option */
+ arg++;
+ switch (*arg) {
+ case 'h':
+ /* help flag */
+ fprintf(stderr,"Decode a lossless JPEG image into ");
+ fprintf(stderr,"a PPM or PGM image.\n");
+ fprintf(stderr,"Usage:\n");
+ fprintf(stderr,"%s\n",usage);
+ fprintf(stderr,"Default input: stdin\n");
+ fprintf(stderr,"Default output: stdout\n");
+ fprintf(stderr,"-h help\n");
+ fprintf(stderr,"-v verbose\n");
+ exit(1);
+ break;
+ case 'v':
+ /* verbose flag */
+ *verbose=1;
+ break;
+ default:
+ fprintf(stderr,"%s\n",usage);
+ exit(-1);
+ }
+ }
+ }
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ DecompressInfo dcInfo;
+ int verbose;
+
+ /*
+ * Process command line parameters.
+ */
+ MEMSET(&dcInfo, 0, sizeof(dcInfo));
+ ArgParser(argc,argv,&verbose,&inFile,&outFile);
+
+ /*
+ * Read the JPEG File header, up to scan header, and initialize all
+ * the variables in the decompression information structure.
+ */
+ ReadFileHeader (&dcInfo);
+
+ /*
+ * Loop through each scan in image. ReadScanHeader returns
+ * 0 once it consumes and EOI marker.
+ */
+ if (!ReadScanHeader (&dcInfo)) {
+ fprintf (stderr, "Empty JPEG file\n");
+ exit (1);
+ }
+
+ /*
+ * Output image parameter if verbose flag is on.
+ */
+ if (verbose) {
+ fprintf(stderr,"sample precision=%d\n",dcInfo.dataPrecision);
+ fprintf(stderr,"image height=%d\n",dcInfo.imageHeight);
+ fprintf(stderr,"image width=%d\n",dcInfo.imageWidth);
+ fprintf(stderr,"component=%d\n",dcInfo.numComponents);
+ }
+
+ /*
+ * Write PPM or PGM image header. Decode the image bits
+ * stream. Clean up everything when finished decoding.
+ */
+ WritePmHeader(dcInfo);
+ DecoderStructInit(&dcInfo);
+ HuffDecoderInit(&dcInfo);
+ DecodeImage(&dcInfo);
+ FreeArray2D(mcuROW1);
+ FreeArray2D(mcuROW2);
+
+ if (ReadScanHeader (&dcInfo)) {
+ fprintf (stderr, "Warning: multiple scans detected in JPEG file\n");
+ fprintf (stderr, " not currently supported\n");
+ fprintf (stderr, " ignoring extra scans\n");
+ }
+
+ return 0;
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/mcu.c b/kernel/kls_ljpeg/ljpeg2ppm/mcu.c
new file mode 100644
index 0000000..bb1f0b3
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/mcu.c
@@ -0,0 +1,125 @@
+/*
+ * mcu.c --
+ *
+ * Support for MCU allocation, deallocation, and printing.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+MCU *mcuTable; /* the global mcu table that buffers the source image */
+MCU *mcuROW1, *mcuROW2; /* point to two rows of MCU in encoding & decoding */
+int numMCU; /* number of MCUs in mcuTable */
+/*
+ *--------------------------------------------------------------
+ *
+ * MakeMCU, InitMcuTable --
+ *
+ * InitMcuTable does a big malloc to get the amount of memory
+ * we'll need for storing MCU's, once we know the size of our
+ * input and output images.
+ * MakeMCU returns an MCU for input parsing.
+ *
+ * Results:
+ * A new MCU
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+InitMcuTable(lnumMCU,compsInScan)
+ int lnumMCU;
+ int compsInScan;
+{
+ int i, mcuSize;
+ char *buffer;
+
+ /*
+ * Compute size of on MCU (in bytes). Round up so it's on a
+ * boundary for any alignment. In this code, we assume this
+ * is a whole multiple of sizeof(double).
+ */
+ mcuSize = compsInScan * sizeof(ComponentType);
+ mcuSize = JroundUp(mcuSize,sizeof(double));
+
+ /*
+ * Allocate the MCU table, and a buffer which will contain all
+ * the data. Then carve up the buffer by hand. Note that
+ * mcuTable[0] points to the buffer, in case we want to free
+ * it up later.
+ */
+ mcuTable = (MCU *)malloc(lnumMCU * sizeof(MCU));
+ if (mcuTable==NULL)
+ fprintf(stderr,"Not enough memory for mcuTable\n");
+ buffer = (char *)malloc(lnumMCU * mcuSize);
+ if (buffer==NULL)
+ fprintf(stderr,"Not enough memory for buffer\n");
+ for (i=0; i<lnumMCU; i++) {
+ mcuTable[i] = (MCU)(buffer + i*mcuSize);
+ }
+}
+
+#define MakeMCU(dcPtr) (mcuTable[numMCU++])
+
+/*
+ *--------------------------------------------------------------
+ *
+ * PrintMCU --
+ *
+ * Send an MCU in quasi-readable form to stdout.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+PrintMCU (compsInScan, mcu)
+ int compsInScan;
+ MCU mcu;
+{
+ ComponentType r;
+ int b;
+ static int callCount;
+
+ for (b=0; b<compsInScan; b++) {
+ callCount++;
+ r = mcu[b];
+ printf ("%d: %d ", callCount, r);
+ printf ("\n");
+ }
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/mcu.h b/kernel/kls_ljpeg/ljpeg2ppm/mcu.h
new file mode 100644
index 0000000..bb894e6
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/mcu.h
@@ -0,0 +1,63 @@
+/*
+ * mcu.h --
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _MCU
+#define _MCU
+
+/*
+ * An MCU (minimum coding unit) is an array of samples.
+ */
+typedef short ComponentType; /* the type of image components */
+typedef ComponentType *MCU; /* MCU - array of samples */
+
+extern MCU *mcuTable; /* the global mcu table that buffers the source image */
+extern int numMCU; /* number of MCUs in mcuTable */
+extern MCU *mcuROW1,*mcuROW2; /* pt to two rows of MCU in encoding & decoding */
+
+/*
+ *--------------------------------------------------------------
+ *
+ * MakeMCU --
+ *
+ * MakeMCU returns an MCU for input parsing.
+ *
+ * Results:
+ * A new MCU
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define MakeMCU(dcPtr) (mcuTable[numMCU++])
+
+#endif /* _MCU */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/predictor.c b/kernel/kls_ljpeg/ljpeg2ppm/predictor.c
new file mode 100644
index 0000000..36dedfd
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/predictor.c
@@ -0,0 +1,189 @@
+/*
+ * predictor.c --
+ *
+ * Code for predictor calculation. Its macro version, predictor.h,
+ * is used in non-debugging compilation.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include "mcu.h"
+
+#ifdef DEBUG
+/*
+ *--------------------------------------------------------------
+ *
+ * Predict --
+ *
+ * Calculate the predictor for pixel[row][col][curComp],
+ * i.e. curRowBuf[col][curComp]. It handles the all special
+ * cases at image edges, such as first row and first column
+ * of a scan.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor)
+ int row,col; /* position of the pixel to be predicted */
+ int curComp; /* the pixel's component that is predicting */
+ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */
+ int Pr; /* data precision */
+ int Pt; /* point transformation */
+ int psv; /* predictor selection value */
+ int *predictor; /* preditor value (output) */
+{
+ register int left,upper,diag,leftcol;
+
+ leftcol=col-1;
+ if (row==0) {
+
+ /*
+ * The predictor of first pixel is (1<<(Pr-Pt-1), and the
+ * predictors for rest of first row are left neighbors.
+ */
+ if (col==0) {
+ *predictor = (1<<(Pr-Pt-1));
+ }
+ else {
+ *predictor = curRowBuf[leftcol][curComp];
+ }
+ }
+ else {
+
+ /*
+ * The predictors of first column are upper neighbors.
+ * All other preditors are calculated according to psv.
+ */
+ upper=prevRowBuf[col][curComp];
+ if (col==0)
+ *predictor = upper;
+ else {
+ left=curRowBuf[leftcol][curComp];
+ diag=prevRowBuf[leftcol][curComp];
+ switch (psv) {
+ case 0:
+ *predictor = 0;
+ break;
+ case 1:
+ *predictor = left;
+ break;
+ case 2:
+ *predictor = upper;
+ break;
+ case 3:
+ *predictor = diag;
+ break;
+ case 4:
+ *predictor = left+upper-diag;
+ break;
+ case 5:
+ *predictor = left+((upper-diag)>>1);
+ break;
+ case 6:
+ *predictor = upper+((left-diag)>>1);
+ break;
+ case 7:
+ *predictor = (left+upper)>>1;
+ break;
+ default:
+ fprintf(stderr,"Warning: Undefined PSV\n");
+ *predictor = 0;
+ }
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * QuickPredict --
+ *
+ * Calculate the predictor for sample curRowBuf[col][curComp].
+ * It does not handle the special cases at image edges, such
+ * as first row and first column of a scan. We put the special
+ * case checkings outside so that the computations in main
+ * loop can be simpler. This has enhenced the performance
+ * significantly.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor)
+ int col; /* column # of the pixel to be predicted */
+ int curComp; /* the pixel's component that is predicting */
+ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */
+ int psv; /* predictor selection value */
+ int *predictor; /* preditor value (output) */
+{
+ register int left,upper,diag,leftcol;
+
+ leftcol=col-1;
+ upper=prevRowBuf[col][curComp];
+ left=curRowBuf[leftcol][curComp];
+ diag=prevRowBuf[leftcol][curComp];
+
+ /*
+ * All predictor are calculated according to psv.
+ */
+ switch (psv) {
+ case 0:
+ *predictor = 0;
+ break;
+ case 1:
+ *predictor = left;
+ break;
+ case 2:
+ *predictor = upper;
+ break;
+ case 3:
+ *predictor = diag;
+ break;
+ case 4:
+ *predictor = left+upper-diag;
+ break;
+ case 5:
+ *predictor = left+((upper-diag)>>1);
+ break;
+ case 6:
+ *predictor = upper+((left-diag)>>1);
+ break;
+ case 7:
+ *predictor = (left+upper)>>1;
+ break;
+ default:
+ fprintf(stderr,"Warning: Undefined PSV\n");
+ *predictor = 0;
+ }
+}
+#endif /*DEBUG*/
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/predictor.h b/kernel/kls_ljpeg/ljpeg2ppm/predictor.h
new file mode 100644
index 0000000..a27b34e
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/predictor.h
@@ -0,0 +1,176 @@
+/*
+ * predictor.h --
+ *
+ * Code for predictor calculation. Its function version, predictor.c,
+ * is used in debugging compilation.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _PREDICTOR
+#define _PREDICTOR
+
+#ifndef DEBUG
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Predict --
+ *
+ * Calculate the predictor for pixel[row][col][curComp],
+ * i.e. curRowBuf[col][curComp]. It handles the all special
+ * cases at image edges, such as first row and first column
+ * of a scan.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor)\
+{ register int left,upper,diag,leftcol; \
+ \
+ leftcol=col-1; \
+ if (row==0) { \
+ \
+ /* \
+ * The predictor of first pixel is (1<<(Pr-Pt-1), and the \
+ * predictors for rest of first row are left neighbors. \
+ */ \
+ if (col==0) { \
+ *predictor = (1<<(Pr-Pt-1)); \
+ } \
+ else { \
+ *predictor = curRowBuf[leftcol][curComp]; \
+ } \
+ } \
+ else { \
+ \
+ /* \
+ * The predictors of first column are upper neighbors. \
+ * All other preditors are calculated according to psv. \
+ */ \
+ upper=prevRowBuf[col][curComp]; \
+ if (col==0) \
+ *predictor = upper; \
+ else { \
+ left=curRowBuf[leftcol][curComp]; \
+ diag=prevRowBuf[leftcol][curComp]; \
+ switch (psv) { \
+ case 0: \
+ *predictor = 0; \
+ break; \
+ case 1: \
+ *predictor = left; \
+ break; \
+ case 2: \
+ *predictor = upper; \
+ break; \
+ case 3: \
+ *predictor = diag; \
+ break; \
+ case 4: \
+ *predictor = left+upper-diag; \
+ break; \
+ case 5: \
+ *predictor = left+((upper-diag)>>1); \
+ break; \
+ case 6: \
+ *predictor = upper+((left-diag)>>1); \
+ break; \
+ case 7: \
+ *predictor = (left+upper)>>1; \
+ break; \
+ default: \
+ fprintf(stderr,"Warning: Undefined PSV\n"); \
+ *predictor = 0; \
+ } \
+ } \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * QuickPredict --
+ *
+ * Calculate the predictor for sample curRowBuf[col][curComp].
+ * It does not handle the special cases at image edges, such
+ * as first row and first column of a scan. We put the special
+ * case checkings outside so that the computations in main
+ * loop can be simpler. This has enhenced the performance
+ * significantly.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor){ \
+ register int left,upper,diag,leftcol; \
+ \
+ leftcol=col-1; \
+ upper=prevRowBuf[col][curComp]; \
+ left=curRowBuf[leftcol][curComp]; \
+ diag=prevRowBuf[leftcol][curComp]; \
+ \
+ /* \
+ * All predictor are calculated according to psv. \
+ */ \
+ switch (psv) { \
+ case 0: \
+ *predictor = 0; \
+ break; \
+ case 1: \
+ *predictor = left; \
+ break; \
+ case 2: \
+ *predictor = upper; \
+ break; \
+ case 3: \
+ *predictor = diag; \
+ break; \
+ case 4: \
+ *predictor = left+upper-diag; \
+ break; \
+ case 5: \
+ *predictor = left+((upper-diag)>>1); \
+ break; \
+ case 6: \
+ *predictor = upper+((left-diag)>>1); \
+ break; \
+ case 7: \
+ *predictor = (left+upper)>>1; \
+ break; \
+ default: \
+ fprintf(stderr,"Warning: Undefined PSV\n"); \
+ *predictor = 0; \
+ } \
+}
+
+#endif /* DEBUG */
+#endif /* _PREDICTOR */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/proto.h b/kernel/kls_ljpeg/ljpeg2ppm/proto.h
new file mode 100644
index 0000000..1188bae
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/proto.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _PROTO
+#define _PROTO
+
+#ifdef __STDC__
+# define P(s) s
+#else
+# define P(s) ()
+#endif
+
+
+/* huffc.c */
+void FlushBytes P((void ));
+void HuffEncoderInit P((CompressInfo *cPtr ));
+void HuffEncode P((CompressInfo *cPtr));
+void HuffEncoderTerm P((void ));
+
+/* huffd.c */
+void HuffDecoderInit P((DecompressInfo *dcPtr ));
+void DecodeImage P((DecompressInfo *dcPtr ));
+
+/* pnmtoljpg.c ljpgtopnm.c */
+int ReadJpegData P((char *buffer , int numBytes ));
+int WriteJpegData P((char *buffer , int numBytes));
+int main P((int argc , char **argv ));
+
+/* read.c */
+void ReadFileHeader P((DecompressInfo *dcPtr ));
+int ReadScanHeader P((DecompressInfo *dcPtr ));
+
+/* write.c */
+void WriteFileTrailer P((CompressInfo *cPtr ));
+void WriteScanHeader P((CompressInfo *cPtr ));
+void WriteFileHeader P((CompressInfo *cPtr ));
+
+/* util.c */
+int JroundUp P((int a , int b ));
+void DecoderStructInit P((DecompressInfo *dcPtr ));
+
+ /* mcu.c */
+void InitMcuTable P((int numMCU , int blocksInMCU ));
+void PrintMCU P((int blocksInMCU , MCU mcu ));
+
+#undef P
+
+#endif /* _PROTO */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/read.c b/kernel/kls_ljpeg/ljpeg2ppm/read.c
new file mode 100644
index 0000000..e4855fd
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/read.c
@@ -0,0 +1,665 @@
+/*
+ * read.c --
+ *
+ * Code for reading and processing JPEG markers. Large parts are grabbed
+ * from the IJG software, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "io.h"
+#include "proto.h"
+
+/*
+ * Enumerate all the JPEG marker codes
+ */
+typedef enum {
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JpegMarker;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Get2bytes --
+ *
+ * Get a 2-byte unsigned integer (e.g., a marker parameter length
+ * field)
+ *
+ * Results:
+ * Next two byte of input as an integer.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static Uint
+Get2bytes (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int a;
+
+ a = GetJpegChar();
+
+ return (a << 8) + GetJpegChar();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SkipVariable --
+ *
+ * Skip over an unknown or uninteresting variable-length marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed over marker.
+ *
+ *
+ *--------------------------------------------------------------
+ */
+static void
+SkipVariable (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+
+ length = Get2bytes (dcPtr) - 2;
+
+ while (length--) {
+ GetJpegChar();
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetDht --
+ *
+ * Process a DHT marker
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * A huffman table is read.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetDht (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+ Uchar bits[17];
+ Uchar huffval[256];
+ int i, index, count;
+ HuffmanTable **htblptr;
+
+ length = Get2bytes (dcPtr) - 2;
+
+ while (length) {
+ index = GetJpegChar();
+
+ bits[0] = 0;
+ count = 0;
+ for (i = 1; i <= 16; i++) {
+ bits[i] = GetJpegChar();
+ count += bits[i];
+ }
+
+ if (count > 256) {
+ fprintf (stderr, "Bogus DHT counts");
+ exit (1);
+ }
+
+ for (i = 0; i < count; i++)
+ huffval[i] = GetJpegChar();
+
+ length -= 1 + 16 + count;
+
+ if (index & 0x10) { /* AC table definition */
+ fprintf(stderr,"Huffman table for lossless JPEG is not defined.\n");
+ } else { /* DC table definition */
+ htblptr = &dcPtr->dcHuffTblPtrs[index];
+ }
+
+ if (index < 0 || index >= 4) {
+ fprintf (stderr, "Bogus DHT index %d", index);
+ exit (1);
+ }
+
+ if (*htblptr == NULL) {
+ *htblptr = (HuffmanTable *) malloc (sizeof (HuffmanTable));
+ if (*htblptr==NULL) {
+ fprintf(stderr,"Can't malloc HuffmanTable\n");
+ exit(-1);
+ }
+ }
+
+ MEMCPY((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
+ MEMCPY((*htblptr)->huffval, huffval, sizeof ((*htblptr)->huffval));
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetDri --
+ *
+ * Process a DRI marker
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Exits on error.
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetDri (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ if (Get2bytes (dcPtr) != 4) {
+ fprintf (stderr, "Bogus length in DRI");
+ exit (1);
+ }
+
+ dcPtr->restartInterval = (Ushort) Get2bytes (dcPtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetApp0 --
+ *
+ * Process an APP0 marker.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Bitstream is parsed
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetApp0 (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+
+ length = Get2bytes (dcPtr) - 2;
+ while (length-- > 0) /* skip any remaining data */
+ (void)GetJpegChar();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSof --
+ *
+ * Process a SOFn marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed
+ * Exits on error
+ * dcPtr structure is filled in
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSof (dcPtr, code)
+ DecompressInfo *dcPtr;
+ int code;
+{
+ int length;
+ short ci;
+ int c;
+ JpegComponentInfo *compptr;
+
+ length = Get2bytes (dcPtr);
+
+ dcPtr->dataPrecision = GetJpegChar();
+ dcPtr->imageHeight = Get2bytes (dcPtr);
+ dcPtr->imageWidth = Get2bytes (dcPtr);
+ dcPtr->numComponents = GetJpegChar();
+
+ /*
+ * We don't support files in which the image height is initially
+ * specified as 0 and is later redefined by DNL. As long as we
+ * have to check that, might as well have a general sanity check.
+ */
+ if ((dcPtr->imageHeight <= 0 ) ||
+ (dcPtr->imageWidth <= 0) ||
+ (dcPtr->numComponents <= 0)) {
+ fprintf (stderr, "Empty JPEG image (DNL not supported)");
+ exit(1);
+ }
+
+ if ((dcPtr->dataPrecision<MinPrecisionBits) ||
+ (dcPtr->dataPrecision>MaxPrecisionBits)) {
+ fprintf (stderr, "Unsupported JPEG data precision");
+ exit(1);
+ }
+
+ if (length != (dcPtr->numComponents * 3 + 8)) {
+ fprintf (stderr, "Bogus SOF length");
+ exit (1);
+ }
+
+ dcPtr->compInfo = (JpegComponentInfo *) malloc
+ (dcPtr->numComponents * sizeof (JpegComponentInfo));
+
+ for (ci = 0; ci < dcPtr->numComponents; ci++) {
+ compptr = &dcPtr->compInfo[ci];
+ compptr->componentIndex = ci;
+ compptr->componentId = GetJpegChar();
+ c = GetJpegChar();
+ compptr->hSampFactor = (c >> 4) & 15;
+ compptr->vSampFactor = (c) & 15;
+ (void) GetJpegChar(); /* skip Tq */
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSos --
+ *
+ * Process a SOS marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSos (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+ int i, ci, n, c, cc;
+ JpegComponentInfo *compptr;
+
+ length = Get2bytes (dcPtr);
+
+ /*
+ * Get the number of image components.
+ */
+ n = GetJpegChar();
+ dcPtr->compsInScan = n;
+ length -= 3;
+
+ if (length != (n * 2 + 3) || n < 1 || n > 4) {
+ fprintf (stderr, "Bogus SOS length");
+ exit (1);
+ }
+
+
+ for (i = 0; i < n; i++) {
+ cc = GetJpegChar();
+ c = GetJpegChar();
+ length -= 2;
+
+ for (ci = 0; ci < dcPtr->numComponents; ci++)
+ if (cc == dcPtr->compInfo[ci].componentId) {
+ break;
+ }
+
+ if (ci >= dcPtr->numComponents) {
+ fprintf (stderr, "Invalid component number in SOS");
+ exit (1);
+ }
+
+ compptr = &dcPtr->compInfo[ci];
+ dcPtr->curCompInfo[i] = compptr;
+ compptr->dcTblNo = (c >> 4) & 15;
+ }
+
+ /*
+ * Get the PSV, skip Se, and get the point transform parameter.
+ */
+ dcPtr->Ss = GetJpegChar();
+ (void)GetJpegChar();
+ c = GetJpegChar();
+ dcPtr->Pt = c & 0x0F;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSoi --
+ *
+ * Process an SOI marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSoi (dcPtr)
+ DecompressInfo *dcPtr;
+{
+
+ /*
+ * Reset all parameters that are defined to be reset by SOI
+ */
+ dcPtr->restartInterval = 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * NextMarker --
+ *
+ * Find the next JPEG marker Note that the output might not
+ * be a valid marker code but it will never be 0 or FF
+ *
+ * Results:
+ * The marker found.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static int
+NextMarker (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, nbytes;
+
+ nbytes = 0;
+ do {
+ /*
+ * skip any non-FF bytes
+ */
+ do {
+ nbytes++;
+ c = GetJpegChar();
+ } while (c != 0xFF);
+ /*
+ * skip any duplicate FFs without incrementing nbytes, since
+ * extra FFs are legal
+ */
+ do {
+ c = GetJpegChar();
+ } while (c == 0xFF);
+ } while (c == 0); /* repeat if it was a stuffed FF/00 */
+
+ return c;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ProcessTables --
+ *
+ * Scan and process JPEG markers that can appear in any order
+ * Return when an SOI, EOI, SOFn, or SOS is found
+ *
+ * Results:
+ * The marker found.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static JpegMarker
+ProcessTables (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c;
+
+ while (1) {
+ c = NextMarker (dcPtr);
+
+ switch (c) {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF2:
+ case M_SOF3:
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ case M_JPG:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ case M_SOI:
+ case M_EOI:
+ case M_SOS:
+ return ((JpegMarker)c);
+
+ case M_DHT:
+ GetDht (dcPtr);
+ break;
+
+ case M_DQT:
+ fprintf(stderr,"Not a lossless JPEG file.\n");
+ break;
+
+ case M_DRI:
+ GetDri (dcPtr);
+ break;
+
+ case M_APP0:
+ GetApp0 (dcPtr);
+ break;
+
+ case M_RST0: /* these are all parameterless */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ fprintf (stderr, "Warning: unexpected marker 0x%02x", c);
+ break;
+
+ default: /* must be DNL, DHP, EXP, APPn, JPGn, COM,
+ * or RESn */
+ SkipVariable (dcPtr);
+ break;
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadFileHeader --
+ *
+ * Initialize and read the file header (everything through
+ * the SOF marker).
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Exit on error.
+ *
+ *--------------------------------------------------------------
+ */
+void
+ReadFileHeader (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, c2;
+
+ /*
+ * Demand an SOI marker at the start of the file --- otherwise it's
+ * probably not a JPEG file at all.
+ */
+ c = GetJpegChar();
+ c2 = GetJpegChar();
+ if ((c != 0xFF) || (c2 != M_SOI)) {
+ fprintf (stderr, "Not a JPEG file\n");
+ exit (1);
+ }
+
+ GetSoi (dcPtr); /* OK, process SOI */
+
+ /*
+ * Process markers until SOF
+ */
+ c = ProcessTables (dcPtr);
+
+ switch (c) {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF3:
+ GetSof (dcPtr, c);
+ break;
+
+ default:
+ fprintf (stderr, "Unsupported SOF marker type 0x%02x", c);
+ break;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadScanHeader --
+ *
+ * Read the start of a scan (everything through the SOS marker).
+ *
+ * Results:
+ * 1 if find SOS, 0 if find EOI
+ *
+ * Side effects:
+ * Bitstream is parsed, may exit on errors.
+ *
+ *--------------------------------------------------------------
+ */
+int
+ReadScanHeader (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c;
+
+ /*
+ * Process markers until SOS or EOI
+ */
+ c = ProcessTables (dcPtr);
+
+ switch (c) {
+ case M_SOS:
+ GetSos (dcPtr);
+ return 1;
+
+ case M_EOI:
+ return 0;
+
+ default:
+ fprintf (stderr, "Unexpected marker 0x%02x", c);
+ break;
+ }
+ return 0;
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/util.c b/kernel/kls_ljpeg/ljpeg2ppm/util.c
new file mode 100644
index 0000000..d5e99cb
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/util.c
@@ -0,0 +1,297 @@
+/*
+ * util.c --
+ *
+ * Various utility routines used in the jpeg encoder/decoder. Large parts
+ * are stolen from the IJG code, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+void FreeArray2D(char **);
+void FixHuffTbl(HuffmanTable *);
+
+unsigned int bitMask[] = { 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
+ 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
+ 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
+ 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
+ 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
+ 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
+ 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
+ 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
+/*
+ *--------------------------------------------------------------
+ *
+ * JroundUp --
+ *
+ * Compute a rounded up to next multiple of b; a >= 0, b > 0
+ *
+ * Results:
+ * Rounded up value.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+int
+JroundUp (a, b)
+ int a, b;
+{
+ a += b - 1;
+ return a - (a % b);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecoderStructInit --
+ *
+ * Initalize the rest of the fields in the decompression
+ * structure.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+DecoderStructInit (dcPtr)
+ DecompressInfo *dcPtr;
+
+{
+ short ci,i;
+ JpegComponentInfo *compPtr;
+ char *buf1,*buf2;
+ int mcuSize;
+
+ /*
+ * Check sampling factor validity.
+ */
+ for (ci = 0; ci < dcPtr->numComponents; ci++) {
+ compPtr = &dcPtr->compInfo[ci];
+ if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
+ fprintf (stderr, "Error: Downsampling is not supported.\n");
+ exit(-1);
+ }
+ }
+
+ /*
+ * Prepare array describing MCU composition
+ */
+ if (dcPtr->compsInScan == 1) {
+ dcPtr->MCUmembership[0] = 0;
+ } else {
+ short lci;
+
+ if (dcPtr->compsInScan > 4) {
+ fprintf (stderr, "Too many components for interleaved scan");
+ exit (1);
+ }
+
+ for (lci = 0; lci < dcPtr->compsInScan; lci++) {
+ dcPtr->MCUmembership[lci] = lci;
+ }
+ }
+
+ /*
+ * Initialize mucROW1 and mcuROW2 which buffer two rows of
+ * pixels for predictor calculation.
+ */
+
+ if ((mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
+ fprintf(stderr,"Not enough memory for mcuROW1\n");
+ }
+ if ((mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
+ fprintf(stderr,"Not enough memory for mcuROW2\n");
+ }
+
+ mcuSize=dcPtr->compsInScan * sizeof(ComponentType);
+ if ((buf1 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
+ fprintf(stderr,"Not enough memory for buf1\n");
+ }
+ if ((buf2 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
+ fprintf(stderr,"Not enough memory for buf2\n");
+ }
+
+ for (i=0;i<dcPtr->imageWidth;i++) {
+ mcuROW1[i]=(MCU)(buf1+i*mcuSize);
+ mcuROW2[i]=(MCU)(buf2+i*mcuSize);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FixHuffTbl --
+ *
+ * Compute derived values for a Huffman table one the DHT marker
+ * has been processed. This generates both the encoding and
+ * decoding tables.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+FixHuffTbl (htbl)
+ HuffmanTable *htbl;
+{
+ int p, i, l, lastp, si;
+ char huffsize[257];
+ Ushort huffcode[257];
+ Ushort code;
+ int size;
+ int value, ll, ul;
+
+ /*
+ * Figure C.1: make table of Huffman code length for each symbol
+ * Note that this is in code-length order.
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ for (i = 1; i <= (int)htbl->bits[l]; i++)
+ huffsize[p++] = (char)l;
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+
+ /*
+ * Figure C.2: generate the codes themselves
+ * Note that this is in code-length order.
+ */
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int)huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ /*
+ * Figure C.3: generate encoding tables
+ * These are code and size indexed by symbol value
+ * Set any codeless symbols to have code length 0; this allows
+ * EmitBits to detect any attempt to emit such symbols.
+ */
+ MEMSET(htbl->ehufsi, 0, sizeof(htbl->ehufsi));
+
+ for (p = 0; p < lastp; p++) {
+ htbl->ehufco[htbl->huffval[p]] = huffcode[p];
+ htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
+ }
+
+ /*
+ * Figure F.15: generate decoding tables
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ if (htbl->bits[l]) {
+ htbl->valptr[l] = p;
+ htbl->mincode[l] = huffcode[p];
+ p += htbl->bits[l];
+ htbl->maxcode[l] = huffcode[p - 1];
+ } else {
+ htbl->maxcode[l] = -1;
+ }
+ }
+
+ /*
+ * We put in this value to ensure HuffDecode terminates.
+ */
+ htbl->maxcode[17] = 0xFFFFFL;
+
+ /*
+ * Build the numbits, value lookup tables.
+ * These table allow us to gather 8 bits from the bits stream,
+ * and immediately lookup the size and value of the huffman codes.
+ * If size is zero, it means that more than 8 bits are in the huffman
+ * code (this happens about 3-4% of the time).
+ */
+ bzero (htbl->numbits, sizeof(htbl->numbits));
+ for (p=0; p<lastp; p++) {
+ size = huffsize[p];
+ if (size <= 8) {
+ value = htbl->huffval[p];
+ code = huffcode[p];
+ ll = code << (8-size);
+ if (size < 8) {
+ ul = ll | bitMask[24+size];
+ } else {
+ ul = ll;
+ }
+ for (i=ll; i<=ul; i++) {
+ htbl->numbits[i] = size;
+ htbl->value[i] = value;
+ }
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FreeArray2D --
+ *
+ * Free the memory of a 2-D array pointed by arrayPtr.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The memory pointed by arrayPtr is freed.
+ *
+ *--------------------------------------------------------------
+ */
+void
+FreeArray2D(arrayPtr)
+ char **arrayPtr;
+{
+ free(arrayPtr[0]);
+ free(arrayPtr);
+}