--- parser3/src/classes/image.C 2003/02/17 07:18:56 1.90.2.8 +++ parser3/src/classes/image.C 2003/03/04 15:59:18 1.90.2.15 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_IMAGE_C="$Date: 2003/02/17 07:18:56 $"; +static const char* IDENT_IMAGE_C="$Date: 2003/03/04 15:59:18 $"; /* jpegsize: gets the width and height (in pixels) of a jpeg file @@ -31,7 +31,7 @@ static const char* IDENT_IMAGE_C="$Date: // class -class MImage : public Methoded { +class MImage: public Methoded { public: // VStateless_class ValuePtr create_new_value() { return ValuePtr(new VImage()); } @@ -45,7 +45,7 @@ public: // Methoded // globals -MethodedPtr image_class(new MImage); +DECLARE_CLASS_VAR(image, new MImage, 0); // helpers @@ -55,7 +55,7 @@ public: EXIF_tag_value2name() { // image JPEG Exif #define EXIF_TAG(tag, name) \ - exif_tag_value2name.put(tag, #name); + put(tag, #name); // Tags used by IFD0 (main image) EXIF_TAG(0x010e, ImageDescription); EXIF_TAG(0x010f, Make); @@ -459,11 +459,11 @@ static ValuePtr parse_IFD_entry_value(Po ushort format=endian_to_ushort(is_big, entry.format); if(format>=sizeof(format2component_size)/sizeof(format2component_size[0])) - return 0; // format out of range, ignoring + return ValuePtr(0); // format out of range, ignoring size_t component_size=format2component_size[format]; if(component_size==0) - return 0; // undefined format + return ValuePtr(0); // undefined format // You can get the total data byte length by multiplies // a 'bytes/components' value (see above chart) by number of components stored 'NNNNNNNN' area @@ -483,7 +483,7 @@ static ValuePtr parse_IFD_entry_value(Po reader.seek(tiff_base+endian_to_uint(is_big, entry.value_or_offset_to_it), SEEK_SET); const char *value; if(reader.read(value, value_size)signature, "Exif\0\0", 4+2)!=0) //signature invalid? - return 0; // ignore invalid block + return ValuePtr(0); // ignore invalid block uint tiff_base=reader.tell(); if(reader.read(buf, sizeof(JPG_Exif_TIFF_header))byte_align_identifier[0]=='M'; // [M]otorola vs [I]ntel @@ -703,10 +703,10 @@ static void file_measure_action(Pool& po measure(pool, info.file_name, reader, *info.width, *info.height, info.exif); } -static void _measure(Request& r, StringPtr method_name, MethodParams& params) { +static void _measure(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); - ValuePtr data=params.as_no_junction(0, "data must not be code"); + ValuePtr data=params->as_no_junction(0, "data must not be code"); ushort width=0; ushort height=0; @@ -754,7 +754,7 @@ static void append_attrib_pair( if(value->is_string() || value->as_int()>=0) *info->tag << "=\"" << value->as_string(info->pool) << "\""; } -static void _html(Request& r, StringPtr method_name, MethodParams& params) { +static void _html(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); String tag; @@ -763,9 +763,9 @@ static void _html(Request& r, StringPtr const HashStringValue& fields=GET_SELF(r, VImage).fields(); HashStringValue* attribs=0; - if(params.count()) { + if(params->count()) { // for backward compatibility: someday was ^html{} - ValuePtr vattribs=r.process_to_value(params.get(0), + ValuePtr vattribs=r.process_to_value(params->get(0), /*0/*no name* /,*/ false/*don't intercept string*/); if(!vattribs->is_string()) // allow empty @@ -804,36 +804,36 @@ static gdImagePtr load(Request& r, Strin } else { throw Exception("file.missing", method_name, - "can not open '%s'", file_name_cstr); + "can not open '%s'", file_name_cstr.get()); return gdImagePtr(0); } } -static void _load(Request& r, StringPtr method_name, MethodParams& params) { +static void _load(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); - StringPtr file_name=params.as_string(0, "file name must not be code"); + StringPtr file_name=params->as_string(0, "file name must not be code"); gdImagePtr image=load(r, method_name, file_name); GET_SELF(r, VImage).set(file_name, image->SX(), image->SY(), image); } -static void _create(Request& r, StringPtr method_name, MethodParams& params) { +static void _create(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); - int width=params.as_int(0, "width must be int", r); - int height=params.as_int(1, "height must be int", r); + int width=params->as_int(0, "width must be int", r); + int height=params->as_int(1, "height must be int", r); int bgcolor_value=0xffFFff; - if(params.count()>2) - bgcolor_value=params.as_int(2, "color must be int", r); + if(params->count()>2) + bgcolor_value=params->as_int(2, "color must be int", r); gdImagePtr image(new gdImage); image->Create(width, height); image->FilledRectangle(0, 0, width-1, height-1, image->Color(bgcolor_value)); GET_SELF(r, VImage).set(StringPtr(0), width, height, image); } -static void _gif(Request& r, StringPtr method_name, MethodParams& params) { +static void _gif(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -849,12 +849,12 @@ static void _gif(Request& r, StringPtr m VFilePtr vfile(new VFile); ValuePtr content_type(new VString(StringPtr(new String("image/gif")))); vfile->set(pool, false/*not tainted*/, - out.cstr(), out.size(), 0, content_type); + out.cstr(pool), out.size(), 0, content_type); r.write_no_lang(vfile); } -static void _line(Request& r, StringPtr method_name, MethodParams& params) { +static void _line(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -864,14 +864,14 @@ static void _line(Request& r, StringPtr "does not contain an image"); image->Line( - params.as_int(0, "x0 must be int", r), - params.as_int(1, "y0 must be int", r), - params.as_int(2, "x1 must be int", r), - params.as_int(3, "y1 must be int", r), - image->Color(params.as_int(4, "color must be int", r))); + params->as_int(0, "x0 must be int", r), + params->as_int(1, "y0 must be int", r), + params->as_int(2, "x1 must be int", r), + params->as_int(3, "y1 must be int", r), + image->Color(params->as_int(4, "color must be int", r))); } -static void _fill(Request& r, StringPtr method_name, MethodParams& params) { +static void _fill(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -881,12 +881,12 @@ static void _fill(Request& r, StringPtr "does not contain an image"); image->Fill( - params.as_int(0, "x must be int", r), - params.as_int(1, "y must be int", r), - image->Color(params.as_int(2, "color must be int", r))); + params->as_int(0, "x must be int", r), + params->as_int(1, "y must be int", r), + image->Color(params->as_int(2, "color must be int", r))); } -static void _rectangle(Request& r, StringPtr method_name, MethodParams& params) { +static void _rectangle(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -896,14 +896,14 @@ static void _rectangle(Request& r, Strin "does not contain an image"); image->Rectangle( - params.as_int(0, "x0 must be int", r), - params.as_int(1, "y0 must be int", r), - params.as_int(2, "x1 must be int", r), - params.as_int(3, "y1 must be int", r), - image->Color(params.as_int(4, "color must be int", r))); + params->as_int(0, "x0 must be int", r), + params->as_int(1, "y0 must be int", r), + params->as_int(2, "x1 must be int", r), + params->as_int(3, "y1 must be int", r), + image->Color(params->as_int(4, "color must be int", r))); } -static void _bar(Request& r, StringPtr method_name, MethodParams& params) { +static void _bar(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -913,11 +913,11 @@ static void _bar(Request& r, StringPtr m "does not contain an image"); image->FilledRectangle( - params.as_int(0, "x0 must be int", r), - params.as_int(1, "y0 must be int", r), - params.as_int(2, "x1 must be int", r), - params.as_int(3, "y1 must be int", r), - image->Color(params.as_int(4, "color must be int", r))); + params->as_int(0, "x0 must be int", r), + params->as_int(1, "y0 must be int", r), + params->as_int(2, "x1 must be int", r), + params->as_int(3, "y1 must be int", r), + image->Color(params->as_int(4, "color must be int", r))); } #ifndef DOXYGEN @@ -928,7 +928,7 @@ static void add_point(Table::element_typ (*p)++; } #endif -static void _replace(Request& r, StringPtr method_name, MethodParams& params) { +static void _replace(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -937,7 +937,7 @@ static void _replace(Request& r, StringP method_name, "does not contain an image"); - Table* table=params.as_no_junction(2, "coordinates must not be code")->get_table(); + Table* table=params->as_no_junction(2, "coordinates must not be code")->get_table(); if(!table) throw Exception(0, method_name, @@ -947,11 +947,11 @@ static void _replace(Request& r, StringP gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->FilledPolygonReplaceColor(all_p, table->count(), - image->Color(params.as_int(0, "src color must be int", r)), - image->Color(params.as_int(1, "dest color must be int", r))); + image->Color(params->as_int(0, "src color must be int", r)), + image->Color(params->as_int(1, "dest color must be int", r))); } -static void _polyline(Request& r, StringPtr method_name, MethodParams& params) { +static void _polyline(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -960,7 +960,7 @@ static void _polyline(Request& r, String method_name, "does not contain an image"); - Table* table=params.as_no_junction(1, "coordinates must not be code")->get_table(); + Table* table=params->as_no_junction(1, "coordinates must not be code")->get_table(); if(!table) throw Exception(0, method_name, @@ -970,11 +970,11 @@ static void _polyline(Request& r, String gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->Polygon(all_p, table->count(), - image->Color(params.as_int(0, "color must be int", r)), + image->Color(params->as_int(0, "color must be int", r)), false/*not closed*/); } -static void _polygon(Request& r, StringPtr method_name, MethodParams& params) { +static void _polygon(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -983,7 +983,7 @@ static void _polygon(Request& r, StringP method_name, "does not contain an image"); - Table* table=params.as_no_junction(1, "coordinates must not be code")->get_table(); + Table* table=params->as_no_junction(1, "coordinates must not be code")->get_table(); if(!table) throw Exception(0, method_name, @@ -993,10 +993,10 @@ static void _polygon(Request& r, StringP gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->Polygon(all_p, table->count(), - image->Color(params.as_int(0, "color must be int", r))); + image->Color(params->as_int(0, "color must be int", r))); } -static void _polybar(Request& r, StringPtr method_name, MethodParams& params) { +static void _polybar(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -1005,7 +1005,7 @@ static void _polybar(Request& r, StringP method_name, "does not contain an image"); - Table* table=params.as_no_junction(1, "coordinates must not be code")->get_table(); + Table* table=params->as_no_junction(1, "coordinates must not be code")->get_table(); if(!table) throw Exception("parser.runtime", method_name, @@ -1015,92 +1015,85 @@ static void _polybar(Request& r, StringP gdImage::Point *add_p=all_p; table->for_each(add_point, &add_p); image->FilledPolygon(all_p, table->count(), - image->Color(params.as_int(0, "color must be int", r))); + image->Color(params->as_int(0, "color must be int", r))); } // font #define Y(y)(y+index*height) -/// simple gdImage-based font storage & text output -class Font: public PA_Object { -public: - - const static int letter_spacing; - int height; ///< Font heigth - int monospace; ///< Default char width - int spacebarspace; ///< spacebar width - gdImagePtr ifont; - StringPtr alphabet; - - Font(//Pool& pool, - StringPtr aalphabet, - gdImagePtr aifont, int aheight, int amonospace, int aspacebarspace): - alphabet(aalphabet), - height(aheight), monospace(amonospace), spacebarspace(aspacebarspace), - ifont(aifont) { - } - - /* ******************************** char ********************************** */ - - int index_of(char ch) { - if(ch==' ') return -1; - return alphabet->pos(&ch, 1); - } - - int index_width(int index) { - if(index<0) - return spacebarspace; - int tr=ifont->GetTransparent(); - for(int x=ifont->SX()-1; x>=0; x--) { - for(int y=0; yGetPixel(x, Y(y))!=tr) - return x+1; - } - return 0; - } - - void index_display(gdImagePtr image, int x, int y, int index){ - if(index>=0) - ifont->Copy(*image, x, y, 0, Y(0), index_width(index), height); - } - - /* ******************************** string ********************************** */ - - int step_width(int index) { - return letter_spacing + (monospace ? monospace : index_width(index)); - } +// Font class + +const int Font::letter_spacing=1; + +Font::Font(//Pool& pool, + StringPtr aalphabet, + gdImagePtr aifont, int aheight, int amonospace, int aspacebarspace): + alphabet(aalphabet), + height(aheight), monospace(amonospace), spacebarspace(aspacebarspace), + ifont(aifont) { +} - // counts trailing letter_spacing, consider this OK. useful for contiuations - int string_width(StringPtr s){ - const char* cstr=s->cstr(); - int result=0; - for(; *cstr; cstr++) - result+=step_width(index_of(*cstr)); - return result; +/* ******************************** char ********************************** */ + +int Font::index_of(char ch) { + if(ch==' ') return -1; + return alphabet->pos(&ch, 1); +} + +int Font::index_width(int index) { + if(index<0) + return spacebarspace; + int tr=ifont->GetTransparent(); + for(int x=ifont->SX()-1; x>=0; x--) { + for(int y=0; yGetPixel(x, Y(y))!=tr) + return x+1; } - - void string_display(gdImagePtr image, int x, int y, StringPtr s){ - const char* cstr=s->cstr(); - if(cstr) for(; *cstr; cstr++) { - int index=index_of(*cstr); - index_display(image, x, y, index); - x+=step_width(index); - } + return 0; +} + +void Font::index_display(gdImagePtr image, int x, int y, int index){ + if(index>=0) + ifont->Copy(*image, x, y, 0, Y(0), index_width(index), height); +} + +/* ******************************** string ********************************** */ + +int Font::step_width(int index) { + return letter_spacing + (monospace ? monospace : index_width(index)); +} + +// counts trailing letter_spacing, consider this OK. useful for contiuations +int Font::string_width(StringPtr s){ + CharPtr cstr=s->cstr(); + int result=0; + for(const char* current=cstr; *current; current++) + result+=step_width(index_of(*current)); + return result; +} + +void Font::string_display(gdImagePtr image, int x, int y, StringPtr s){ + CharPtr cstr=s->cstr(); + for(const char* current=cstr; *current; current++) { + int index=index_of(*current); + index_display(image, x, y, index); + x+=step_width(index); } - -}; -const int Font::letter_spacing=1; +} + +// + -static void _font(Request& r, StringPtr method_name, MethodParams& params) { +static void _font(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); - StringPtr alphabet=params.as_string(0, "alphabet must not be code"); - gdImagePtr image=load(r, method_name, params.as_string(1, "file_name must not be code")); - int spacebar_width=params.as_int(2, "spacebar_width must be int", r); + StringPtr alphabet=params->as_string(0, "alphabet must not be code"); + gdImagePtr image=load(r, method_name, params->as_string(1, "file_name must not be code")); + int spacebar_width=params->as_int(2, "spacebar_width must be int", r); int monospace_width; - if(params.count()>3) { - monospace_width=params.as_int(3, "monospace_width must be int", r); + if(params->count()>3) { + monospace_width=params->as_int(3, "monospace_width must be int", r); if(!monospace_width) monospace_width=image->SX(); } else @@ -1123,12 +1116,12 @@ static void _font(Request& r, StringPtr image->SY() / alphabet->size(), monospace_width, spacebar_width)); } -static void _text(Request& r, StringPtr method_name, MethodParams& params) { +static void _text(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); - int x=params.as_int(0, "x must be int", r); - int y=params.as_int(1, "y must be int", r); - StringPtr s=params.as_string(2, "text must not be code"); + int x=params->as_int(0, "x must be int", r); + int y=params->as_int(1, "y must be int", r); + StringPtr s=params->as_string(2, "text must not be code"); VImage& vimage=GET_SELF(r, VImage); if(vimage.image) @@ -1144,10 +1137,10 @@ static void _text(Request& r, StringPtr "does not contain an image"); } -static void _length(Request& r, StringPtr method_name, MethodParams& params) { +static void _length(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); - const StringPtr s=params.as_string(0, "text must not be code"); + const StringPtr s=params->as_string(0, "text must not be code"); VImage& vimage=GET_SELF(r, VImage); if(vimage.image) @@ -1163,7 +1156,7 @@ static void _length(Request& r, StringPt "does not contain an image"); } -static void _arc(Request& r, StringPtr method_name, MethodParams& params) { +static void _arc(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -1173,16 +1166,16 @@ static void _arc(Request& r, StringPtr m "does not contain an image"); image->Arc( - params.as_int(0, "center_x must be int", r), - params.as_int(1, "center_y must be int", r), - params.as_int(2, "width must be int", r), - params.as_int(3, "height must be int", r), - params.as_int(4, "start degrees must be int", r), - params.as_int(5, "end degrees must be int", r), - image->Color(params.as_int(6, "cx must be int", r))); + params->as_int(0, "center_x must be int", r), + params->as_int(1, "center_y must be int", r), + params->as_int(2, "width must be int", r), + params->as_int(3, "height must be int", r), + params->as_int(4, "start degrees must be int", r), + params->as_int(5, "end degrees must be int", r), + image->Color(params->as_int(6, "cx must be int", r))); } -static void _sector(Request& r, StringPtr method_name, MethodParams& params) { +static void _sector(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -1192,16 +1185,16 @@ static void _sector(Request& r, StringPt "does not contain an image"); image->Sector( - params.as_int(0, "center_x must be int", r), - params.as_int(1, "center_y must be int", r), - params.as_int(2, "width must be int", r), - params.as_int(3, "height must be int", r), - params.as_int(4, "start degrees must be int", r), - params.as_int(5, "end degrees must be int", r), - image->Color(params.as_int(6, "color must be int", r))); + params->as_int(0, "center_x must be int", r), + params->as_int(1, "center_y must be int", r), + params->as_int(2, "width must be int", r), + params->as_int(3, "height must be int", r), + params->as_int(4, "start degrees must be int", r), + params->as_int(5, "end degrees must be int", r), + image->Color(params->as_int(6, "color must be int", r))); } -static void _circle(Request& r, StringPtr method_name, MethodParams& params) { +static void _circle(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr image=GET_SELF(r, VImage).image; @@ -1210,22 +1203,22 @@ static void _circle(Request& r, StringPt method_name, "does not contain an image"); - int size=params.as_int(2, "radius must be int", r)*2; + int size=params->as_int(2, "radius must be int", r)*2; image->Arc( - params.as_int(0, "center_x must be int", r), - params.as_int(1, "center_y must be int", r), + params->as_int(0, "center_x must be int", r), + params->as_int(1, "center_y must be int", r), size, //w size, //h 0, //s 360, //e - image->Color(params.as_int(3, "color must be int", r))); + image->Color(params->as_int(3, "color must be int", r))); } -gdImagePtr as_image(Pool& pool, StringPtr method_name, MethodParams& params, +gdImagePtr as_image(Pool& pool, StringPtr method_name, MethodParams* params, int index, const char* msg) { gdImagePtr src(0); - ValuePtr value=params.as_no_junction(index, msg); + ValuePtr value=params->as_no_junction(index, msg); if(Value* vimage=value->as(VIMAGE_TYPE, false)) { src=static_cast(vimage)->image; @@ -1241,7 +1234,7 @@ gdImagePtr as_image(Pool& pool, StringPt return src; } -static void _copy(Request& r, StringPtr method_name, MethodParams& params) { +static void _copy(Request& r, StringPtr method_name, MethodParams* params) { Pool& pool=r.pool(); gdImagePtr dest=GET_SELF(r, VImage).image; @@ -1252,18 +1245,18 @@ static void _copy(Request& r, StringPtr gdImagePtr src=as_image(pool, method_name, params, 0, "src must be image"); - int sx=params.as_int(1, "src_x must be int", r); - int sy=params.as_int(2, "src_y must be int", r); - int sw=params.as_int(3, "src_w must be int", r); - int sh=params.as_int(4, "src_h must be int", r); - int dx=params.as_int(5, "dest_x must be int", r); - int dy=params.as_int(6, "dest_y must be int", r); - if(params.count()>1+2+2+2) { - int dw=params.as_int(1+2+2+2, "dest_w must be int", r); - int dh=(int)(params.count()>1+2+2+2+1? - params.as_int(1+2+2+2+1, "dest_h must be int", r):sh*(((double)dw)/((double)sw))); - int tolerance=params.count()>1+2+2+2+2? - params.as_int(1+2+2+2+2, "tolerance must be int", r):150; + int sx=params->as_int(1, "src_x must be int", r); + int sy=params->as_int(2, "src_y must be int", r); + int sw=params->as_int(3, "src_w must be int", r); + int sh=params->as_int(4, "src_h must be int", r); + int dx=params->as_int(5, "dest_x must be int", r); + int dy=params->as_int(6, "dest_y must be int", r); + if(params->count()>1+2+2+2) { + int dw=params->as_int(1+2+2+2, "dest_w must be int", r); + int dh=(int)(params->count()>1+2+2+2+1? + params->as_int(1+2+2+2+1, "dest_h must be int", r):sh*(((double)dw)/((double)sw))); + int tolerance=params->count()>1+2+2+2+2? + params->as_int(1+2+2+2+2, "tolerance must be int", r):150; src->CopyResampled(*dest, dx, dy, sx, sy, dw, dh, sw, sh, tolerance); } else