summaryrefslogtreecommitdiff
path: root/Build/source/utils/sam2p/image.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/sam2p/image.hpp')
-rw-r--r--Build/source/utils/sam2p/image.hpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/Build/source/utils/sam2p/image.hpp b/Build/source/utils/sam2p/image.hpp
new file mode 100644
index 00000000000..d339a9f14c1
--- /dev/null
+++ b/Build/source/utils/sam2p/image.hpp
@@ -0,0 +1,377 @@
+/* image.hpp -- classes for sampled (indexed, gray and rgb) images
+ * by pts@fazekas.hu Wed Feb 27 09:24:47 CET 2002
+ */
+/* Imp: find memory leaks */
+/* Imp: keep future transparency in toIndexed(...) */
+
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#ifndef SAMPLED_HPP
+#define SAMPLED_HPP 1
+
+#include "config2.h"
+#include "gensi.hpp"
+
+class Image {
+ public:
+ class RGB;
+ class Gray;
+ class Indexed;
+ /** Generic, sampled, rectangular image data. Abstract class.
+ * Each sample is 1, 2, 4 or 8 bits. Regions:
+ * beg..head-1: comment, ignored (e.g unused part of the indexed palette)
+ * headp..rowbeg-1: header: not predicted or compressed (e.g the indexed palette)
+ * rowbeg+0*rlen..rowbeg+0*rlen+rlen-1: sample data of the 0th row, compressed and predicted
+ * rowbeg+1*rlen..rowbeg+1*rlen+rlen-1: sample data of the 1st row
+ * rowbeg+2*rlen..rowbeg+2*rlen+rlen-1: sample data of the 1st row
+ * ...
+ * rowbeg+(h-1)*rlen..rowbeg+h*rlen-1: sample data of the last row
+ * trail..beg+len: trailer, ignored. Its length must be >=bpc.
+ */
+ class Sampled: public SimBuffer::Flat {
+ public:
+ /** Can hold 1 component of a sample of a single pixel. */
+ typedef unsigned char sample_t;
+ /** Can hold a height or depth of the image */
+ typedef unsigned int dimen_t;
+ /** Can hold a row length (in byte), which isn't greater than 3*(image width). */
+ typedef unsigned int rlen_t;
+ /** RGB = (red<<16)+(green<<8)+(blue). red, green and blue are 0..255 */
+ #if SIZEOF_LONG>4 && SIZEOF_INT>=4
+ typedef unsigned int rgb_t;
+ #else
+ typedef unsigned long rgb_t;
+ #endif
+ BEGIN_STATIC_ENUM1(unsigned char)
+ TY_INDEXED=1, TY_GRAY=2, TY_RGB=3, TY_OTHER=4, TY_BLACKBOX=5
+ END_STATIC_ENUM()
+ BEGIN_STATIC_ENUM1(unsigned char) // static const unsigned char
+ CS_UNKNOWN=0, /* error/unspecified */
+ CS_GRAYSCALE=1, /* monochrome */
+ CS_RGB=2, /* red/green/blue */
+ CS_YCbCr=3, /* Y/Cb/Cr (also known as YUV) */
+ CS_CMYK=4, /* C/M/Y/K */
+ CS_YCCK=5, /* Y/Cb/Cr/K */
+ CS_Indexed_RGB=12
+ END_STATIC_ENUM()
+ static const unsigned char cs2cpp[6];
+ /** @return NULLP on error */
+ static char const *cs2devcs(unsigned char cs);
+ protected:
+ char *headp;
+ char *rowbeg;
+ char *trail;
+ /** Extra offset */
+ slen_t xoffs;
+
+ /** Length of one row, in bytes. Each row must begin on a byte boundary, so
+ * extra bits are appended after the rightmost pixel. These bits are
+ * arbitrary, and are ignored by the PostScript interpreter.
+ */
+ rlen_t rlen;
+ /** Image height, in pixels. */
+ dimen_t ht;
+ /** Image width, in pixels. */
+ dimen_t wd;
+ /** Color space. */
+ unsigned char cs;
+ /** Components per pixel. (number of planes, image depth). 1 for indexed,
+ * 1 for gray, 3 for RGB
+ */
+ unsigned char cpp;
+ /** BitsPerComponent: 1, 2, 4 or 8. PostScript allows 12 too. */
+ unsigned char bpc;
+ /** Transparent color value. Imp: ... */
+ rgb_t transpc;
+ /** Image type, TY_... */
+ unsigned char ty;
+ /** Initializes various fields, allocates memory. Called from descendants'
+ * constructors.
+ */
+ void init(slen_t l_comment, slen_t l_header, dimen_t wd_, dimen_t ht_,
+ unsigned char bpc_, unsigned char ty_, unsigned char cpp_);
+ /** Convert samples, make bpc=8, multiplication. */
+ void to8mul();
+ /** Convert samples, make bpc=8, no multiplication. */
+ void to8nomul();
+ /** Calls copyRGBRow.
+ * @return an Image::Indexed version of (this) iff the number of
+ * colors<=256. Otherwise, returns NULLP.
+ */
+ Indexed* toIndexed0()/* const*/;
+ /** No averaging is done, only the red component is extracted */
+ Gray* toGray0(unsigned char bpc_);
+ RGB * toRGB0(unsigned char bpc_);
+ /** @return if any pixels are not gray: false. otherwise: true or false. */
+ public:
+ inline bool hasTransp() const { return transpc!=0x1000000UL; }
+ virtual bool canGray() const =0;
+ /** @return an RGB BitsPerComponent number (1,2,4 or 8) to which the image
+ * could be converted without any loss. The default implementation calls
+ * copyRGBRow().
+ */
+ virtual unsigned char minRGBBpc() const;
+ inline virtual ~Sampled() { delete [] const_cast<char*>(beg); }
+ /** Copies whichrow as wd*3 bytes (R0,G0,B0,R1,G1,B1...) to `to' */
+ virtual void copyRGBRow(char *to, dimen_t whichrow) const =0;
+ virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const;
+ inline char *getRowbeg() const { return rowbeg; }
+ inline dimen_t getWd() const { return wd; }
+ inline dimen_t getHt() const { return ht; }
+ inline unsigned char getTy() const { return ty; }
+ inline unsigned char getBpc() const { return bpc; }
+ inline unsigned char getCpp() const { return cpp; }
+ inline unsigned char getCs() const { return cs; }
+ inline slen_t getXoffs() const { return xoffs; }
+ inline rlen_t getRlen() const { return rlen; }
+ inline rgb_t getTranspc() const { return transpc; }
+ inline char *getHeadp() const { return headp; }
+ /** Convert samples, make bpc=8. */
+ virtual void to8() =0;
+ /** @return NULLP if too many colors for indexed; otherwise a new Image::Indexed.
+ * The caller should `delete' (this) if toIndexed()==NULLP.
+ */
+ virtual /*Image::*/Indexed* toIndexed() =0;
+ virtual /*Image::*/RGB* toRGB(unsigned char bpc_) =0;
+ virtual /*Image::*/Gray* toGray(unsigned char bpc_) =0;
+ // virtual void setBpc(unsigned char bpc_) =0;
+ friend GenBuffer::Writable& operator<<(GenBuffer::Writable&, /*Image::*/Sampled const&);
+ /** @return address of static buffer: "#RRGGBB" */
+ static char *rgb2webhash(rgb_t);
+ /** @return (this) or an image containing (this) composed with alpha
+ * channel `al'
+ */
+ virtual Sampled* addAlpha(/*Image::*/Gray *al) =0;
+ /** assert(al.bpp=8) etc. Imp: document this */
+ static Indexed* addAlpha0(Sampled *img, Gray *al);
+ };
+
+ class Indexed: public Sampled {
+ public:
+ /** @param ncols_ must be >= the colors used */
+ Indexed(dimen_t wd_, dimen_t ht_, unsigned short ncols_, unsigned char bpc_);
+ inline unsigned short getNcols() const { return (rowbeg-headp)/3; }
+ /** Destroys the color table, and creates one with ncols_ colors.
+ * @param ncols_ must be <= the ncols_ specified in the constructor
+ */
+ void setNcols(unsigned short ncols_);
+ /** Decreases the size of the palette (forgets last colors) to the
+ * specified amount.
+ */
+ void setNcolsMove(unsigned short ncols_);
+ void setPal(unsigned char coloridx, rgb_t rgb);
+ rgb_t getPal(unsigned char coloridx) const;
+ /** @param coloridx must be >=0, transp must be -1 */
+ void setTransp(unsigned char coloridx);
+ /** @return new hasTransp */
+ bool setTranspc(rgb_t color);
+ virtual void copyRGBRow(char *to, dimen_t whichrow) const;
+ /* virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const; */
+ /** Packs (compresses) the palette so that it will be continuous in
+ * 0..ncols-1, and each color will be used exactly once. The
+ * transparent color (if present) will become black. As a side-effect,
+ * packPal() may set (this)->bpc=8.
+ */
+ void packPal();
+ virtual void to8();
+ virtual /*Image::*/Indexed* toIndexed();
+ virtual /*Image::*/RGB* toRGB(unsigned char bpc_);
+ virtual /*Image::*/Gray* toGray(unsigned char bpc_);
+ virtual bool canGray() const;
+ inline signed short getTransp() const { return transp; }
+ inline signed short getClearTransp() { signed short ret=transp; transp=-1; return ret; }
+ /** if (transp>0) transp=0;, converts image data. Does not change bpc. */
+ void makeTranspZero();
+ virtual unsigned char minRGBBpc() const;
+ /** Separates the current image into Indexed1 images. The caller is
+ * recommended to call packPal() first to reduce the number of required
+ * images.
+ * As a side-effect,
+ * separate() may set (this)->bpc=8.
+ * @return the array of images after full color separation: that is
+ * a dynamically allocated array of `getNcols()-(getTransp()!=-1)'
+ * Indexed images: each image is Indexed1, color 0 is opaque (with the
+ * color obtained from (this)), color 1 is transparent. The returned
+ * array is NULLP-terminated.
+ */
+ Indexed **separate();
+ /** Also calls packPal(). As a side effect, changes all transparent
+ * pixels to color index 0.
+ * @return NULLP if no transparent pixels.
+ */
+ Indexed *calcAlpha();
+ /** Deletes all elements of p, but not p itself.
+ * @param p a NULLP-terminated list of (Indexed*)s.
+ */
+ static void delete_separated(Indexed **p);
+ /** Reorganizes the image so it will have the specified bpc. Issues a
+ * runtime error if the specified bpc cannot be achieved.
+ * @param bpc_ the desired bpc, or 0: the best achievable.
+ */
+ virtual void setBpc(unsigned char bpc_);
+ void dumpDebug(GenBuffer::Writable& gw);
+ protected:
+ /* Index of the transparent color, or -1. */
+ signed short transp;
+ virtual /*Image::*/Sampled* addAlpha(/*Image::*/Gray *al);
+ };
+ class Gray: public Sampled {
+ public:
+ Gray(dimen_t wd_, dimen_t ht_, unsigned char bpc_);
+ virtual void copyRGBRow(char *to, dimen_t whichrow) const;
+ virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const;
+ virtual void to8();
+ virtual /*Image::*/Indexed* toIndexed();
+ virtual bool canGray() const;
+ // virtual void setBpc(unsigned char bpc_);
+ virtual /*Image::*/RGB * toRGB(unsigned char bpc_);
+ virtual /*Image::*/Gray * toGray(unsigned char bpc_);
+ virtual /*Image::*/Sampled* addAlpha(/*Image::*/Gray *al);
+ /** Calls to8(). */
+ void calcExtrema(unsigned char &lightest, unsigned char &darkest);
+ };
+ class RGB: public Sampled {
+ public:
+ RGB(dimen_t wd_, dimen_t ht_, unsigned char bpc_);
+ virtual void copyRGBRow(char *to, dimen_t whichrow) const;
+ /* virtual bool hasPixelRGB(Image::Sampled::rgb_t rgb) const; */
+ virtual void to8();
+ virtual /*Image::*/Indexed* toIndexed();
+ virtual bool canGray() const;
+ // virtual void setBpc(unsigned char bpc_);
+ virtual /*Image::*/RGB * toRGB(unsigned char bpc_);
+ virtual /*Image::*/Gray * toGray(unsigned char bpc_);
+ virtual /*Image::*/Sampled* addAlpha(/*Image::*/Gray *al);
+ };
+
+ /** Avoid including <stdio.h> */
+ typedef void *filep_t;
+
+ /** Describes a driver that can load a specific image file format. */
+ struct Loader {
+ /** Filter::UngetFILED */
+ class UFD;
+ /** A function that can (allocate and) load a sampled image. Never
+ * returns NULL. On error, it calls Error::.... The filep_t argument
+ * should be really cast back to FILE*. The reader must fclose the FILE*.
+ */
+ // typedef Sampled*(*reader_t)(filep_t, SimBuffer::Flat const& loadHints);
+ typedef Sampled*(*reader_t)(UFD* ufd, SimBuffer::Flat const& loadHints);
+ BEGIN_STATIC_ENUM1(unsigned) MAGIC_LEN=64 END_STATIC_ENUM()
+ /** A function that checks the magic numbers at the beginning of a file
+ * (already read into buf), and returns NULL if it cannot load an image
+ * of that type, or a reader_t that will load the image. If (and only if!)
+ * file is shorter than 64 bytes, the buf is padded with '\000' bytes.
+ * @param f may read from freely if necessary (MAGIC_LEN is short), but
+ * has to call rewind(f) before reading
+ */
+ typedef reader_t(*checker_t)(char buf[MAGIC_LEN], char bufend[MAGIC_LEN], SimBuffer::Flat const& loadHints, UFD* ufd);
+ /** A null-terminated, compact string describing (not defining!) the image
+ * file format.
+ * Examples: "GIF", "XPM", "PNM"
+ */
+ char const*format;
+ checker_t checker;
+ /** Null or next loader. */
+ Loader *next;
+ };
+
+ /** Registers a new type of image Loader, i.e a new image file format. The
+ * new image format will be put in front of all others, and will be checked
+ * first
+ */
+ static void register0(Loader *);
+ /** Loads the image contained in te file `filename'.
+ * @param format NULLP is unknown (load any format)
+ * or an Image::Loader::format already registered
+ */
+ static Sampled* load(Loader::UFD* ufd, SimBuffer::Flat const& loadHints, char const* format);
+ static Sampled* load(char const *filename, SimBuffer::Flat const& loadHints, filep_t stdin_f=(filep_t*)NULLP, char const* format=(char const*)NULLP);
+ /* Prints the list of available Loaders (->format), separated by spaces.
+ * Returns the number of available Loaders. Prepends a space if >= loaders.
+ */
+ static unsigned printLoaders(GenBuffer::Writable &);
+
+ /** SampleFormat constants */
+ BEGIN_STATIC_ENUM(unsigned, sf_t)
+ SF_None=0, /* no specific sample format */
+ SF_Opaque=1,
+ SF_Transparent=2,
+ SF_Gray1=3,
+ SF_Indexed1=4,
+ SF_Mask=5,
+ SF_Transparent2=6,
+ SF_Gray2=7,
+ SF_Indexed2=8,
+ SF_Transparent4=9,
+ SF_Rgb1=10,
+ SF_Gray4=11,
+ SF_Indexed4=12,
+ SF_Transparent8=13,
+ SF_Rgb2=14,
+ SF_Gray8=15,
+ SF_Indexed8=16,
+ SF_Rgb4=17,
+ SF_Rgb8=18,
+ SF_Asis=19,
+ SF_Bbox=20,
+ SF_max=31
+ END_STATIC_ENUM()
+
+ /** Contains (and memory-manages) an image, and optimization information
+ * as a cache.
+ */
+ class SampledInfo {
+ public:
+ SampledInfo(Sampled *img_);
+ ~SampledInfo();
+ inline Sampled* getImage() const { return img; }
+ /**
+ * Source image, may be modified even if TryOnly==false. If
+ * modified, the original will be freed.
+ * @param sf desired sample format, see Image::SF_* constants
+ * @param WarningOK if false: make the conversion fail if it would produces
+ * a Warning
+ * @param TryOnly if true: don't do the real conversion (but may do auxilary,
+ * idempontent, helper conversion), assume it has succeeded
+ * @param Transparent: as part of the conversion, try to make this RGB color
+ * transparent
+ * @return true iff the conversion succeeded. Note that img may be the same
+ * pointer even when true is returned
+ */
+ bool setSampleFormat(sf_t sf, bool WarningOK, bool TryOnly, Sampled::rgb_t Transparent);
+ inline Indexed **getImgs() const { return imgs; }
+ inline Sampled *getImg() const { return img; }
+ inline unsigned getNncols() const { return nncols; }
+ void separate();
+ inline bool canGrayy() const { return canGray; }
+ inline unsigned char minRGBBpcc() const { return minRGBBpc; }
+ inline bool hasTranspp() const { return hasTransp; }
+ inline unsigned char minGrayBpcc() const { return canGray ? minRGBBpc : 0; }
+ inline void clearTransp() { hasTransp=false; }
+ protected:
+ bool hasTransp;
+ /** Number of non-transparent colors, or 257 if >=257. */
+ unsigned nncols;
+ /** Has only gray colors. */
+ bool canGray;
+ unsigned char minRGBBpc;
+ Sampled *img;
+ /** The array of images after full color separation. May be NULLP (default),
+ * or a dynamically allocated array of `nncols' Indexed images: each
+ * image is Indexed1, color 0 is opaque (with any value), color 1
+ * is transparent.
+ */
+ Indexed **imgs;
+ sf_t sf;
+ };
+};
+
+/** Dumps this Image as a rawbits PPM file (plus a comment indicating transparency)
+ * @return the Writable.
+ */
+GenBuffer::Writable& operator<<(GenBuffer::Writable&, Image::Sampled const&);
+
+#endif