1 /* rule.hpp -- Output rules 2 * by pts@fazekas.hu Fri Mar 15 15:11:38 CET 2002 3 */ 4 5 #ifdef __GNUC__ 6 #ifndef __clang__ 7 #pragma interface 8 #endif 9 #endif 10 11 #ifndef RULE_HPP 12 #define RULE_HPP 1 13 14 #include "config2.h" 15 #include "gensio.hpp" 16 #include "image.hpp" 17 #include "minips.hpp" 18 19 /** a namespace */ 20 class Rule { public: 21 struct Cache { 22 bool WarningOK; 23 BEGIN_STATIC_ENUM(unsigned char,ff_t) 24 FF_default=0, /* only for one-liner */ 25 FF_eps=71, /* only for one-liner, temporary */ 26 FF_pdf=72, /* only for one-liner, temporary */ 27 FF_pdfb=73, /* only for one-liner, temporary */ 28 FF_PSL1=110, 29 FF_PSLC=115, 30 FF_PSL2=120, 31 FF_PSL3=130, 32 FF_PDFB10=90, 33 FF_PDFB12=92, 34 FF_PDF10=80, 35 FF_PDF12=82, 36 FF_GIF89a=1, 37 FF_PNM=2, 38 FF_PAM=3, 39 FF_PIP=4, /* Portable Indexed file format by pts */ 40 FF_Empty=5, 41 FF_Meta=6, 42 FF_JPEG=7, 43 FF_TIFF=8, 44 FF_PNG=9, 45 FF_XPM=10, 46 FF_BMP=11, 47 FF_XWD=12, 48 FF_X11=13 /* Don't add a comma, gcc-4.8.1. can't compile it that way. */ 49 END_STATIC_ENUM() 50 ff_t FileFormat; 51 Image::sf_t SampleFormat; 52 /** Used only in appliers.cpp when _check_rule() changes SampleFormat so 53 * setSampleFormat() called before _work() would set that dummy 54 * SampleFormat. 55 */ 56 Image::sf_t origSampleFormat; 57 BEGIN_STATIC_ENUM(unsigned char,te_t) 58 TE_default=0, /* only for one-liner */ 59 TE_Binary=1, 60 TE_ASCII=2, 61 TE_Hex=3, 62 TE_A85=4, 63 TE_MSBfirst=5, 64 TE_LSBfirst=6 65 END_STATIC_ENUM() 66 te_t TransferEncoding; 67 68 BEGIN_STATIC_ENUM(unsigned char,co_t) 69 CO_default=0, /* only for one-liner */ 70 CO_None=1, 71 CO_LZW=2, 72 CO_ZIP=3, 73 CO_RLE=4, 74 CO_Fax=5, 75 CO_DCT=6, 76 CO_IJG=7, 77 CO_JAI=8, 78 CO_max=8 79 END_STATIC_ENUM() 80 co_t Compression; 81 82 BEGIN_STATIC_ENUM(unsigned char,pr_t) 83 PR_None=1, 84 PR_TIFF2=2, 85 PR_PNGNone=10, PR_PNG=10, 86 PR_PNGSub=11, 87 PR_PNGUP=12, 88 PR_PNGAverage=13, 89 PR_PNGPaeth=14, 90 PR_PNGAuto=15, 91 PR_PNGAutoMaybe=25, 92 PR_PNGAutoBadUnsigned=45, 93 PR_PNGAutoBadSigned=55 94 END_STATIC_ENUM() 95 pr_t Predictor; 96 97 Image::Sampled::rgb_t Transparent; 98 99 bool isOneBit() const; 100 bool isPDF() const; 101 bool isPDFB() const; 102 bool isPS() const; 103 bool isPSL2() const; 104 bool isPSL3() const; 105 bool hasPredictor() const; 106 bool isIndexed() const; 107 bool isTransparentM() const; 108 bool isGray() const; 109 bool isRGB() const; 110 bool isDCTE() const; 111 bool isBinSB() const; 112 /** /Compression/ZIP not OK with /PSL1, /PSLC, /PSL2, /PDF10, /PDFB10 */ 113 bool isZIPOK() const; 114 // bool is8() const; 115 116 /** @param s is case insensitive, leading `/' is optional. 117 * @return SF_max if not found, or a valid SF_... constant 118 */ 119 static Image::sf_t parseSampleFormat(char const*s, slen_t slen); 120 static char const* dumpFileFormat(ff_t FileFormat, co_t Compression=CO_default); 121 static char const* dumpTransferEncoding(te_t TransferEncoding); 122 static char const* dumpSampleFormat(Image::sf_t SampleFormat); 123 static char const* dumpCompression(co_t Compression); 124 }; 125 126 struct CacheHints { 127 BEGIN_STATIC_ENUM(unsigned char,sc_t) /* Fri Aug 16 16:33:47 CEST 2002 */ 128 SC_default=0, 129 SC_None=1, 130 SC_OK=2, 131 SC_RotateOK=3 132 END_STATIC_ENUM() 133 sc_t Scale; 134 135 /* Image dimensions for encoding filters (may be different from real 136 * image dimensions, but _really_ disrecommended). 137 * slen_t important becasuse of separate(). 138 */ 139 slen_t EncoderColumns, EncoderBPL, EncoderRows; 140 /** Number of color components (channels) per pixel. */ 141 unsigned char EncoderColors; 142 slen_t PredictorColumns; 143 unsigned char PredictorBPC, PredictorColors; 144 unsigned ColorTransform; 145 signed Effort; 146 slen_t RecordSize; 147 slendiff_t K; 148 /* JPEG quality for the IJG encoding filter */ 149 unsigned char Quality; 150 unsigned TransferCPL; 151 MiniPS::String *Comment, *Title, *Subject, *Author, *Creator, *Producer; 152 MiniPS::String *Created, *Produced; 153 MiniPS::Dict *DCT; 154 /** MiniPS::Real* or integer */ 155 MiniPS::VALUE TopMargin, BottomMargin, LeftMargin, RightMargin; 156 /** MiniPS::Real* or integer. Specifies the dimension the image should 157 * be lowered below the baseline for (PostScript or PDF) output with 158 * /Scale/None. Default to 0. 159 */ 160 MiniPS::VALUE LowerMargin; 161 /** 72 by default. */ 162 MiniPS::VALUE ImageDPI; 163 static char const* dumpScale(sc_t Scale); 164 }; 165 166 struct OutputRule { 167 Cache cache; 168 CacheHints cacheHints; 169 MiniPS::Dict* dict; 170 /* /Hints entry in dict */ 171 MiniPS::Dict* dictHints; 172 /* Number of this output rule, as appeared in .job. Imp: name */ 173 unsigned c; isEOLRule::OutputRule174 inline bool isEOL() const { return dictHints==NULLP; } 175 /** In: dict, dictHints, cache and cacheHints is uninitialized. Out: they 176 * get inititalized from param. Errors might occur and error messages 177 * might get printed. 178 */ 179 void fromDict(MiniPS::VALUE); 180 /** Calls info->setSampleFormat(), and sets cacheHints.PredictorColumns 181 * and some other fields if they are zero (unspecified in the .job file) 182 */ 183 void doSampleFormat(Image::SampledInfo *info, bool separate=false); 184 /** Appends "" when CO_None, 185 * "<</K ... /Columns ...>>/CCITTFaxDecode filter" when CO_Fax 186 * "/...Decode filter" otherwise 187 * Calls appendPredictorSpec() if necessary. 188 * For PDF (not PS!), implies appendTransferSpec(). 189 */ 190 void appendDecoderSpec(GenBuffer::Writable &out) const; 191 /** Appends "" when PR_None or 192 * appends "<</BitsPerComponent.../Colors.../Columns.../Predictor 2>>" or 193 * appends "<</BitsPerComponent.../Colors.../Columns.../Predictor 10>>" 194 * appends "<</K ...>>" 195 */ 196 void appendPredictorSpec(GenBuffer::Writable &out) const; 197 /** Appends "" or "/ASCII85Decode filter" or "/ASCIIHexDecode filter" 198 */ 199 void appendTransferSpec(GenBuffer::Writable &out) const; 200 bool hasPredictorSpec() const; 201 }; 202 203 struct Applier { 204 BEGIN_STATIC_ENUM(unsigned,cons_t) 205 DONT_KNOW=0, BAD=1, MAYBE=2, OK=3 206 END_STATIC_ENUM() 207 /** Checks the specified OutputRule for internal consistency, updates 208 * the `or->cache', emits warnings, and returns consistency status 209 * information. 210 * 211 * -- If (this) Applier doesn't know how to handle the OutputRule, returns 212 * DONT_KNOW immediately. 213 * -- If (this) Applier knows that the OutputRule is internally 214 * inconsistent or proved to be unsupported (i.e printing JPEG images 215 * on PostScript Level1 printers), regardless of the image itself, it 216 * returns BAD immediately and emits a warning about the reason. 217 * -- If (this) Applier knows that the OutputRule may or may not be 218 * processed, depending on the actual image, then MAYBE is returned. 219 * -- If (this) Applier knows that the OutputRule can be processed on 220 * any image, then OK is returned. 221 */ 222 typedef cons_t(*check_rule_t)(OutputRule* or_); 223 224 /** Outputs (writes) the PostScript or PDF presentation of the image 225 * specified in param `sf' to the output stream in param `out', using 226 * the Output Rule specified in param `or'. 227 * @return DONT_KNOW if doesn't know how to handle the OutputRule; 228 * BAD if it is sure that the image cannot be written with the 229 * specified OutputRule; 230 * OK if writing was successful 231 */ 232 typedef cons_t(*work_t)(GenBuffer::Writable& out, OutputRule*or_, Image::SampledInfo *sf); 233 234 /** A short, informal description of this Applier. */ 235 char const*format; 236 check_rule_t check_rule; 237 /** May be NULLP if `check_rule' never returns OK or MAYBE */ 238 work_t work; 239 /** Null or next Applier to probe. Filled by register0(); */ 240 Applier *next; 241 }; 242 243 /* Registers a new type of output Applier, i.e a new output file 244 * format/method. The new output format will be put in front of all others, 245 * and will be checked first by apply_best(). 246 */ 247 static void register0(Applier*); 248 /* Loads the image contained in te file `filename'. */ 249 250 /** Builds the list of available profiles from the Profile element read 251 * from a .job file. To do the task, calls check_rule() of all registered (!) 252 * Appliers. Also calls OutputRule::fromDict for each profile element. 253 * All returned OutputRules have an Applier which returned OK or MAYBE. 254 * @return a dict==NULLP-terminated list of OutputRules 255 */ 256 static OutputRule* buildProfile(MiniPS::VALUE Profile, bool quiet=false); 257 258 /** Applies the Profile specified in param `rule_list' to the image 259 * specified in param `sf', and writes the output to param `out'. 260 */ 261 static void applyProfile(GenBuffer::Writable& out, OutputRule*rule_list, Image::SampledInfo *sf); 262 263 /** Frees memory associated with a profile returned by buildProfile() */ 264 static void deleteProfile(OutputRule*); 265 266 static unsigned printAppliers(GenBuffer::Writable &out); 267 268 269 typedef void (*stream_writer_t)(GenBuffer::Writable&out, GenBuffer::Writable&outstream, Image::SampledInfo *sf); 270 271 /** Writes a PS/PDF file to `out' according to `template_': substitutes 272 * actual image (pixel) data from `sf->getImg()', and substitutes image 273 * metadata from `sf'. `outstream' should be a prepared stream (top of chain 274 * of Encode filters). 275 * See a .tte file for an example template. 276 */ 277 static void writeTTE( 278 GenBuffer::Writable& out, 279 GenBuffer::Writable& outpal, 280 GenBuffer::Writable& outstream, 281 char const*template_, 282 Rule::OutputRule*or_, 283 Image::SampledInfo *sf, 284 stream_writer_t stream_writer, 285 char const*const*strings=(char**)NULLP); 286 287 /** Doesn't invoke MiniPS::delete0(chunkArray); */ 288 static void writeTTM( 289 Filter::VerbatimE &outve, 290 GenBuffer::Writable&outpal, 291 GenBuffer::Writable&outstream, 292 MiniPS::Array *chunkArray, 293 Rule::OutputRule*or_, 294 Image::SampledInfo *sf, 295 stream_writer_t stream_writer, 296 char const*const*strings=(char**)NULLP); 297 298 /** Used by writeTTT() to find template specification by name */ 299 static MiniPS::Dict* Templates; 300 /** @param out must be of type Filter::VerbatimE if the template is a TTM 301 * array. 302 * @param template_key a key in file bts.ttt 303 */ 304 static void writeTTT( 305 GenBuffer::Writable&out, 306 GenBuffer::Writable&outpal, 307 GenBuffer::Writable&outstream, 308 char const *template_key, 309 Rule::OutputRule*or_, 310 Image::SampledInfo *sf, 311 stream_writer_t stream_writer, 312 char const*const*strings=(char**)NULLP); 313 314 static void writeData(GenBuffer::Writable& out, GenBuffer::Writable&outstream, Image::SampledInfo *sf); 315 static void writePalData(GenBuffer::Writable& out, GenBuffer::Writable&outstream, Image::SampledInfo *sf); 316 317 }; 318 319 #endif 320