diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 17:43:19 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 17:43:19 +0000 |
commit | 0292059f4a16434600564cfa3f0ad2309a508a54 (patch) | |
tree | d95953cd53011917c4df679b96aedca39401b54f /kernel/kls_ljpeg | |
download | libksquirrel-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.am | 17 | ||||
-rw-r--r-- | kernel/kls_ljpeg/fmt_codec_pnm.cpp | 1470 | ||||
-rw-r--r-- | kernel/kls_ljpeg/fmt_codec_pnm_defs.h | 64 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ksquirrel-libs-ljpeg2ppm-s.in | 18 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/Copyright | 79 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/Makefile.am | 5 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/huffd.c | 665 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/io.h | 105 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/jpeg.h | 249 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c | 263 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/mcu.c | 125 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/mcu.h | 63 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/predictor.c | 189 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/predictor.h | 176 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/proto.h | 75 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/read.c | 665 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/util.c | 297 |
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); +} |