00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef SCRIPT_IMAGESCRIPT_C_DEFINED
00039 #define SCRIPT_IMAGESCRIPT_C_DEFINED
00040
00041 #include "Script/ImageScript.H"
00042
00043 #include "Image/Image.H"
00044 #include "Image/Pixels.H"
00045 #include "Image/ShapeOps.H"
00046 #include "Raster/Raster.H"
00047 #include "Util/log.H"
00048
00049 #include "rutz/error.h"
00050 #include "rutz/fstring.h"
00051 #include "rutz/sfmt.h"
00052
00053 #include "tcl/conversions.h"
00054 #include "tcl/list.h"
00055 #include "tcl/obj.h"
00056 #include "tcl/pkg.h"
00057
00058 #include <cstdio>
00059 #include <cstdlib>
00060 #include <tcl.h>
00061
00062 template <class T>
00063 struct ImageObj
00064 {
00065 static Tcl_ObjType objType;
00066
00067 static Tcl_ObjType* objTypePtr() { return &objType; }
00068
00069 static Tcl_Obj* make(const Image<T>& img);
00070
00071 static void freeInternalRep(Tcl_Obj* objPtr);
00072
00073 static void dupInternalRep(Tcl_Obj* srcPtr, Tcl_Obj* dupPtr);
00074
00075 static void updateString(Tcl_Obj* objPtr);
00076
00077 static int setFromAny(Tcl_Interp* interp, Tcl_Obj* objPtr);
00078 };
00079
00080 template <class T>
00081 Tcl_Obj* ImageObj<T>::make(const Image<T>& img)
00082 {
00083 Tcl_Obj* objPtr = Tcl_NewObj();
00084 objPtr->typePtr = &ImageObj<T>::objType;
00085 objPtr->internalRep.otherValuePtr = new Image<T>(img);
00086
00087 LDEBUG("new Image: %p", objPtr->internalRep.otherValuePtr);
00088
00089 Tcl_InvalidateStringRep(objPtr);
00090
00091 return objPtr;
00092 }
00093
00094 template <class T>
00095 void ImageObj<T>::freeInternalRep(Tcl_Obj* objPtr)
00096 {
00097 Image<T>* iobj =
00098 static_cast<Image<T>*>(objPtr->internalRep.otherValuePtr);
00099
00100 LDEBUG("delete Image: %p", iobj);
00101
00102 delete iobj;
00103
00104 objPtr->internalRep.otherValuePtr = 0;
00105 }
00106
00107 template <class T>
00108 void ImageObj<T>::dupInternalRep(Tcl_Obj* srcPtr, Tcl_Obj* dupPtr)
00109 {
00110 if (dupPtr->typePtr != 0 && dupPtr->typePtr->freeIntRepProc != 0)
00111 {
00112 dupPtr->typePtr->freeIntRepProc(dupPtr);
00113 }
00114
00115 Image<T>* iobj =
00116 static_cast<Image<T>*>(srcPtr->internalRep.otherValuePtr);
00117
00118 LDEBUG("dup Image: %p (src)", iobj);
00119
00120 dupPtr->internalRep.otherValuePtr =
00121 static_cast<void*>(new Image<T>(*iobj));
00122
00123 LDEBUG("dup Image: %p (dst)", dupPtr->internalRep.otherValuePtr);
00124
00125 dupPtr->typePtr = &ImageObj<T>::objType;
00126 }
00127
00128 template <class T>
00129 void ImageObj<T>::updateString(Tcl_Obj* objPtr)
00130 {
00131 Image<T>* iobj =
00132 static_cast<Image<T>*>(objPtr->internalRep.otherValuePtr);
00133
00134 ASSERT(iobj != 0);
00135
00136 ASSERT(objPtr->bytes == 0);
00137
00138 rutz::fstring s =
00139 rutz::sfmt("{{%s:%dx%d}",
00140 ImageObj<T>::objType.name,
00141 iobj->getWidth(), iobj->getHeight());
00142
00143 LDEBUG("string Image: %p", iobj);
00144
00145 objPtr->bytes = Tcl_Alloc(s.length()+1);;
00146 strcpy(objPtr->bytes, s.c_str());
00147 objPtr->length = s.length();
00148 }
00149
00150 template <class T>
00151 int ImageObj<T>::setFromAny(Tcl_Interp* interp, Tcl_Obj* objPtr)
00152 {
00153 Tcl_AppendResult(interp, "can't convert to image type");
00154 return TCL_ERROR;
00155 }
00156
00157 namespace
00158 {
00159 template <class T>
00160 tcl::obj image2tcl(Image<T> img) { return ImageObj<T>::make(img); }
00161
00162 template <class T>
00163 Image<T> tcl2image(Tcl_Obj* obj)
00164 {
00165 if (obj->typePtr == &ImageObj<T>::objType)
00166 {
00167 Image<T>* iobj =
00168 static_cast<Image<T>*>(obj->internalRep.otherValuePtr);
00169 return *iobj;
00170 }
00171
00172 throw rutz::error
00173 (rutz::sfmt
00174 ("wrong object type:\n"
00175 "\t got: %s\n"
00176 "\texpected: %s",
00177 obj->typePtr ? obj->typePtr->name : "(unknown)",
00178 ImageObj<T>::objType.name),
00179 SRC_POS);
00180
00181 return Image<T>();
00182 }
00183 }
00184
00185 tcl::obj tcl::aux_convert_from(Dims d)
00186 {
00187 tcl::list result;
00188 result.append(d.w());
00189 result.append(d.h());
00190 return result.as_obj();
00191 }
00192
00193 Dims tcl::aux_convert_to(Tcl_Obj* obj, Dims*)
00194 {
00195 tcl::list l(obj);
00196 return Dims(l.get<int>(0), l.get<int>(1));
00197 }
00198
00199 #define INST_IMG_OBJ_TYPE(T) \
00200 tcl::obj tcl::aux_convert_from(Image< T > img) \
00201 { return image2tcl(img); } \
00202 \
00203 Image< T > tcl::aux_convert_to(Tcl_Obj* obj, Image<T>*) \
00204 { return tcl2image< T >(obj); } \
00205 \
00206 template <> \
00207 Tcl_ObjType ImageObj< T >::objType = \
00208 { \
00209 const_cast<char*>("Image<" #T ">"), \
00210 &ImageObj< T >::freeInternalRep, \
00211 &ImageObj< T >::dupInternalRep, \
00212 &ImageObj< T >::updateString, \
00213 &ImageObj< T >::setFromAny \
00214 }
00215
00216
00217 INST_IMG_OBJ_TYPE(byte);
00218 INST_IMG_OBJ_TYPE(float);
00219 INST_IMG_OBJ_TYPE(PixRGB<byte>);
00220 INST_IMG_OBJ_TYPE(PixRGB<float>);
00221
00222 namespace
00223 {
00224 template <class T>
00225 Image<T> makeImage(unsigned int w, unsigned int h)
00226 {
00227 return Image<T>(w, h, ZEROS);
00228 }
00229
00230 template <class T>
00231 rutz::fstring describeImage(const Image<T>& img)
00232 {
00233 return rutz::sfmt("here it is: {%dx%d}",
00234 img.getWidth(), img.getHeight());
00235 }
00236
00237 template <class T>
00238 bool imageInitialized(const Image<T>& img)
00239 {
00240 return img.initialized();
00241 }
00242
00243 Image<byte> readGray(const char* fname)
00244 { return Raster::ReadGray(fname); }
00245
00246 Image<float> readFloat(const char* fname)
00247 { return Raster::ReadFloat(fname); }
00248
00249 Image<PixRGB<byte> > readRGB(const char* fname)
00250 { return Raster::ReadRGB(fname); }
00251
00252
00253 void writeGray(Image<byte> img, const char* fname)
00254 { Raster::WriteGray(img, fname); }
00255
00256 void writeFloat(Image<float> img, int flags, const char* fname)
00257 { Raster::WriteFloat(img, flags, fname); }
00258
00259 void writeRGB(Image<PixRGB<byte> > img, const char* fname)
00260 { Raster::WriteRGB(img, fname); }
00261
00262 template <class T>
00263 int imgInit(Tcl_Interp* interp, const char* pkgname)
00264 {
00265 GVX_PKG_CREATE(pkg, interp, pkgname, "4.$Revision: 1$");
00266
00267 Tcl_RegisterObjType(&ImageObj<T>::objType);
00268
00269 pkg->def("make", "w h", &makeImage<T>, SRC_POS);
00270 pkg->def("describe", "img", &describeImage<T>, SRC_POS);
00271 pkg->def("initialized", "img", &imageInitialized<T>, SRC_POS);
00272 pkg->def("zoom", "img xzoom yzoom", &zoomXY<T>, SRC_POS);
00273
00274 GVX_PKG_RETURN(pkg);
00275 }
00276 }
00277
00278 extern "C"
00279 int Bimage_Init(Tcl_Interp* interp)
00280 {
00281 return imgInit<byte>(interp, "BImage");
00282 }
00283
00284 extern "C"
00285 int Fimage_Init(Tcl_Interp* interp)
00286 {
00287 return imgInit<float>(interp, "FImage");
00288 }
00289
00290 extern "C"
00291 int Cbimage_Init(Tcl_Interp* interp)
00292 {
00293 return imgInit<PixRGB<byte> >(interp, "CBImage");
00294 }
00295
00296 extern "C"
00297 int Cfimage_Init(Tcl_Interp* interp)
00298 {
00299 return imgInit<PixRGB<float> >(interp, "CFImage");
00300 }
00301
00302 extern "C"
00303 int Raster_Init(Tcl_Interp* interp)
00304 {
00305 GVX_PKG_CREATE(pkg, interp, "Raster", "4.$Revision: 1$");
00306
00307 pkg->def("readGray", "fname", &readGray, SRC_POS);
00308 pkg->def("readFloat", "fname", &readFloat, SRC_POS);
00309 pkg->def("readRGB", "fname", &readRGB, SRC_POS);
00310
00311 pkg->def("writeGray", "img fname", &writeGray, SRC_POS);
00312 pkg->def("writeFloat", "img flags fname", &writeFloat, SRC_POS);
00313 pkg->def("writeRGB", "img fname", &writeRGB, SRC_POS);
00314
00315 GVX_PKG_RETURN(pkg);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 #endif // SCRIPT_IMAGESCRIPT_C_DEFINED