[q-lang-cvs] q/modules/magick magick.c,1.3,1.4 magick.q,1.3,1.4
Brought to you by:
agraef
From: <ag...@us...> - 2003-12-24 03:05:39
|
Update of /cvsroot/q-lang/q/modules/magick In directory sc8-pr-cvs1:/tmp/cvs-serv15621 Modified Files: magick.c magick.q Log Message: working on the magick module Index: magick.c =================================================================== RCS file: /cvsroot/q-lang/q/modules/magick/magick.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** magick.c 23 Dec 2003 13:14:43 -0000 1.3 --- magick.c 24 Dec 2003 03:05:36 -0000 1.4 *************** *** 180,184 **** static void get_pixels(unsigned char *dest, PixelPacket *source, ! unsigned long count) { unsigned long i; --- 180,184 ---- static void get_pixels(unsigned char *dest, PixelPacket *source, ! unsigned long count, unsigned matte) { unsigned long i; *************** *** 188,198 **** p = source; q = (unsigned short*)dest; ! for (i = 0; i < count; i++) { ! *q++=ScaleQuantumToShort(p->red); ! *q++=ScaleQuantumToShort(p->green); ! *q++=ScaleQuantumToShort(p->blue); ! *q++=ScaleQuantumToShort(MaxRGB-p->opacity); ! p++; ! } } --- 188,207 ---- p = source; q = (unsigned short*)dest; ! if (matte) ! for (i = 0; i < count; i++) { ! *q++=ScaleQuantumToShort(p->red); ! *q++=ScaleQuantumToShort(p->green); ! *q++=ScaleQuantumToShort(p->blue); ! *q++=ScaleQuantumToShort(MaxRGB-p->opacity); ! p++; ! } ! else ! for (i = 0; i < count; i++) { ! *q++=ScaleQuantumToShort(p->red); ! *q++=ScaleQuantumToShort(p->green); ! *q++=ScaleQuantumToShort(p->blue); ! *q++=ScaleQuantumToShort(MaxRGB); ! p++; ! } } *************** *** 200,204 **** static void set_pixels(PixelPacket *dest, unsigned char *source, ! unsigned long count) { unsigned long i; --- 209,213 ---- static void set_pixels(PixelPacket *dest, unsigned char *source, ! unsigned long count, unsigned matte) { unsigned long i; *************** *** 208,232 **** p = (unsigned short*)source; q = dest; ! for (i = 0; i < count; i++) { ! q->red=ScaleShortToQuantum(*p++); ! q->green=ScaleShortToQuantum(*p++); ! q->blue=ScaleShortToQuantum(*p++); ! q->opacity=ScaleShortToQuantum(0xffff-*p++); ! q++; ! } } /* parse info tuples */ ! static int parse_info(int n, expr *xv, ImageInfo *info) { int i = 0; ! unsigned long width, height, depth; char *magick; static char geom[100]; if (i >= n) return 1; if (!isuint(xv[i++], &width)) return 0; if (i >= n) return 1; ! if (!isuint(xv[i++], &height)) height = 0; if (width > 0 && height > 0) { sprintf(geom, "%ux%u", width, height); --- 217,250 ---- p = (unsigned short*)source; q = dest; ! if (matte) ! for (i = 0; i < count; i++) { ! q->red=ScaleShortToQuantum(*p++); ! q->green=ScaleShortToQuantum(*p++); ! q->blue=ScaleShortToQuantum(*p++); ! q->opacity=ScaleShortToQuantum(0xffff-*p++); ! q++; ! } ! else ! for (i = 0; i < count; i++) { ! q->red=ScaleShortToQuantum(*p++); ! q->green=ScaleShortToQuantum(*p++); ! q->blue=ScaleShortToQuantum(*p++); ! q++; ! } } /* parse info tuples */ ! static int parse_info(int n, expr *xv, ImageInfo *info, int *_matte) { int i = 0; ! unsigned long width, height, depth, matte; char *magick; static char geom[100]; + *_matte = -1; if (i >= n) return 1; if (!isuint(xv[i++], &width)) return 0; if (i >= n) return 1; ! if (!isuint(xv[i++], &height)) return 0; if (width > 0 && height > 0) { sprintf(geom, "%ux%u", width, height); *************** *** 238,259 **** info->depth = depth; if (i >= n) return 1; ! if (!istrue(xv[i]) && !isfalse(xv[i])) return 0; ! if (++i >= n) return 1; ! if (!isstr(xv[i++], &magick)) return 0; ! strncpy(info->magick, magick, MaxTextExtent-1); ! if (i >= n) return 1; ! return 0; ! } ! ! static int parse_info2(int n, expr *xv, Image *img) ! { ! int i = 3; ! char *magick; ! if (i >= n) return 1; ! if (!istrue(xv[i]) && !isfalse(xv[i])) return 0; ! img->matte = istrue(xv[i++])!=0; if (i >= n) return 1; if (!isstr(xv[i++], &magick)) return 0; ! if (!*img->magick) strncpy(img->magick, magick, MaxTextExtent-1); if (i >= n) return 1; return 0; --- 256,264 ---- info->depth = depth; if (i >= n) return 1; ! if (!isuint(xv[i++], &matte) || matte > 1) return 0; ! *_matte = (int)matte; if (i >= n) return 1; if (!isstr(xv[i++], &magick)) return 0; ! strncpy(info->magick, magick, MaxTextExtent-1); if (i >= n) return 1; return 0; *************** *** 291,295 **** } m->size = 8; ! get_pixels(m->v, &pixel, 1); return mkobj(type(ByteStr), m); skip: --- 296,300 ---- } m->size = 8; ! get_pixels(m->v, &pixel, 1, 1); return mkobj(type(ByteStr), m); skip: *************** *** 329,333 **** return __FAIL; } ! get_pixels(v, &pixel, 1); } return mkobj(type(ByteStr), m); --- 334,338 ---- return __FAIL; } ! get_pixels(v, &pixel, 1, 1); } return mkobj(type(ByteStr), m); *************** *** 338,347 **** expr *xv; int n = 0; ! if (argc == 1 && (istuple(argv[0], &n, &xv) || isvoid(argv[0])) && ! n <= 5) { ImageInfo *info = CloneImageInfo(NULL); Image *img; if (!info) return __ERROR; ! if (!parse_info(n, xv, info)) { DestroyImageInfo(info); return __FAIL; --- 343,358 ---- expr *xv; int n = 0; ! bstr_t *m; ! unsigned long w, h; ! if (argc == 2 && istuple(argv[0], &n, &xv) && n >= 2 && n <= 5 && ! isuint(xv[0], &w) && isuint(xv[1], &h) && w > 0 && h > 0 && ! isobj(argv[1], type(ByteStr), (void**)&m)) { ! unsigned long size = w*h*8; ImageInfo *info = CloneImageInfo(NULL); Image *img; + int matte; if (!info) return __ERROR; ! if (ULONG_MAX/8 < w*h || m->size != 8 && m->size != size || ! !parse_info(n, xv, info, &matte)) { DestroyImageInfo(info); return __FAIL; *************** *** 349,360 **** img = AllocateImage(info); DestroyImageInfo(info); - if (img && !parse_info2(n, xv, img)) { - DestroyImage(img); - return __FAIL; - } if (!img) return __ERROR; ! else ! return mkobj(type(Image), img); } else return __FAIL; --- 360,388 ---- img = AllocateImage(info); DestroyImageInfo(info); if (!img) return __ERROR; ! else { ! PixelPacket *pixels; ! if (matte >= 0) img->matte = (unsigned)matte; ! if (!(pixels = SetImagePixels(img, 0, 0, w, h))) { ! DestroyImage(img); ! return __FAIL; ! } ! if (m->size > 8) ! set_pixels(pixels, m->v, w*h, img->matte); ! else { ! unsigned long x, y; ! for (y = 0; y < h; y++, pixels += w) ! for (x = 0; x < w; x++) ! set_pixels(pixels+x, m->v, 1, img->matte); ! } ! img->storage_class = DirectClass; ! if (SyncImagePixels(img)) ! return mkobj(type(Image), img); ! else { ! DestroyImage(img); ! return __FAIL; ! } ! } } else return __FAIL; *************** *** 386,391 **** ImageInfo *info = CloneImageInfo(NULL); Image *img; if (!info) return __ERROR; ! if (!parse_info(n, xv, info)) { DestroyImageInfo(info); return __FAIL; --- 414,420 ---- ImageInfo *info = CloneImageInfo(NULL); Image *img; + int matte; if (!info) return __ERROR; ! if (!parse_info(n, xv, info, &matte)) { DestroyImageInfo(info); return __FAIL; *************** *** 396,407 **** if (check_exception(&exception)) return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); - if (img && !parse_info2(n, xv, img)) { - DestroyImage(img); - return __FAIL; - } if (!img) return __FAIL; ! else return mkobj(type(Image), img); } else return __FAIL; --- 425,434 ---- if (check_exception(&exception)) return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); if (!img) return __FAIL; ! else { ! if (matte >= 0) img->matte = (unsigned)matte; return mkobj(type(Image), img); + } } else return __FAIL; *************** *** 431,434 **** --- 458,532 ---- } + FUNCTION(magick,image_to_blob,argc,argv) + { + char *s = NULL; + Image *img; + if (argc == 2 && + isobj(argv[1], type(Image), (void**)&img) && + img->columns > 0 && img->rows > 0 && + (isvoid(argv[0]) && *img->magick || isstr(argv[0], &s) && *s)) { + ImageInfo *info = CloneImageInfo(NULL); + size_t len; + void *blob; + bstr_t *m; + char magick[MaxTextExtent]; + if (!info) return __ERROR; + if (s) { + strncpy(magick, img->magick, MaxTextExtent-1); + strncpy(img->magick, s, MaxTextExtent-1); + } + blob = ImageToBlob(info, img, &len, &exception); + if (s) + strncpy(img->magick, magick, MaxTextExtent-1); + DestroyImageInfo(info); + if (check_exception(&exception)) + return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); + else if (!blob) + return __FAIL; + else if ((int)len < 0 || !(m = malloc(sizeof(bstr_t)))) { + free(blob); + return __ERROR; + } else { + m->size = (int)len; + m->v = (char*)blob; + return mkobj(type(ByteStr), m); + } + } else + return __FAIL; + } + + FUNCTION(magick,blob_to_image,argc,argv) + { + bstr_t *m; + expr *xv; + int n = 0; + if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && + m->size > 0 && + (istuple(argv[1], &n, &xv) || isvoid(argv[1])) && + n <= 5) { + ImageInfo *info = CloneImageInfo(NULL); + Image *img; + int matte; + size_t len = (size_t)m->size; + void *blob = m->v; + if (!info) return __ERROR; + if (!parse_info(n, xv, info, &matte)) { + DestroyImageInfo(info); + return __FAIL; + } + img = BlobToImage(info, blob, len, &exception); + DestroyImageInfo(info); + if (check_exception(&exception)) + return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); + if (!img) + return __FAIL; + else { + if (matte >= 0) img->matte = (unsigned)matte; + return mkobj(type(Image), img); + } + } else + return __FAIL; + } + FUNCTION(magick,image_info,argc,argv) { *************** *** 437,441 **** return mktuplel(5, mkuint(img->columns), mkuint(img->rows), mkuint(img->depth), ! img->matte?mktrue:mkfalse, mkstr(strdup(img->magick))); else --- 535,539 ---- return mktuplel(5, mkuint(img->columns), mkuint(img->rows), mkuint(img->depth), ! mkuint((unsigned long)img->matte), mkstr(strdup(img->magick))); else *************** *** 535,539 **** } m->size = size; ! get_pixels(m->v, pixels, w*h); return mkobj(type(ByteStr), m); } else --- 633,637 ---- } m->size = size; ! get_pixels(m->v, pixels, w*h, img->matte); return mkobj(type(ByteStr), m); } else *************** *** 563,567 **** if (!(pixels = SetImagePixels(img, x, y, w, h))) return __FAIL; ! set_pixels(pixels, m->v, w*h); img->storage_class = DirectClass; if (SyncImagePixels(img)) --- 661,665 ---- if (!(pixels = SetImagePixels(img, x, y, w, h))) return __FAIL; ! set_pixels(pixels, m->v, w*h, img->matte); img->storage_class = DirectClass; if (SyncImagePixels(img)) *************** *** 569,644 **** else return __FAIL; - } else - return __FAIL; - } - - FUNCTION(magick,image_to_blob,argc,argv) - { - char *s = NULL; - Image *img; - if (argc == 2 && - isobj(argv[1], type(Image), (void**)&img) && - img->columns > 0 && img->rows > 0 && - (isvoid(argv[0]) && *img->magick || isstr(argv[0], &s) && *s)) { - ImageInfo *info = CloneImageInfo(NULL); - size_t len; - void *blob; - bstr_t *m; - char magick[MaxTextExtent]; - if (!info) return __ERROR; - if (s) { - strncpy(magick, img->magick, MaxTextExtent-1); - strncpy(img->magick, s, MaxTextExtent-1); - } - blob = ImageToBlob(info, img, &len, &exception); - if (s) - strncpy(img->magick, magick, MaxTextExtent-1); - DestroyImageInfo(info); - if (check_exception(&exception)) - return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); - else if (!blob) - return __FAIL; - else if ((int)len < 0 || !(m = malloc(sizeof(bstr_t)))) { - free(blob); - return __ERROR; - } else { - m->size = (int)len; - m->v = (char*)blob; - return mkobj(type(ByteStr), m); - } - } else - return __FAIL; - } - - FUNCTION(magick,blob_to_image,argc,argv) - { - bstr_t *m; - expr *xv; - int n = 0; - if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && - m->size > 0 && - (istuple(argv[1], &n, &xv) || isvoid(argv[1])) && - n <= 5) { - ImageInfo *info = CloneImageInfo(NULL); - Image *img; - size_t len = (size_t)m->size; - void *blob = m->v; - if (!info) return __ERROR; - if (!parse_info(n, xv, info)) { - DestroyImageInfo(info); - return __FAIL; - } - img = BlobToImage(info, blob, len, &exception); - DestroyImageInfo(info); - if (check_exception(&exception)) - return mkapp(mksym(sym(magick_error)), mkstr(strdup(msg))); - if (img && !parse_info2(n, xv, img)) { - DestroyImage(img); - return __FAIL; - } - if (!img) - return __FAIL; - else - return mkobj(type(Image), img); } else return __FAIL; --- 667,670 ---- Index: magick.q =================================================================== RCS file: /cvsroot/q-lang/q/modules/magick/magick.q,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** magick.q 23 Dec 2003 13:14:43 -0000 1.3 --- magick.q 24 Dec 2003 03:05:36 -0000 1.4 *************** *** 51,56 **** intensity. Similarly, an alpha value of 0 denotes a fully transparent, 0xffff a fully opaque pixel. Note that this format matches the layout of ! GGI pixel values, which makes it easy to transfer pixel data between images ! and GGI visuals. */ /* The magick_pixel function returns the normalized RGBA color value, as a --- 51,56 ---- intensity. Similarly, an alpha value of 0 denotes a fully transparent, 0xffff a fully opaque pixel. Note that this format matches the layout of ! GGI pixel values, which makes it easy to transfer pixel data between ! ImageMagick images and GGI visuals. */ /* The magick_pixel function returns the normalized RGBA color value, as a *************** *** 59,108 **** the range 0..0xffff; the alpha value is optional and is assumed to be 0xffff if it is missing. The function also packs a list of such values into ! a single byte string. The result of magick_pixel is suitable to be used as ! the DATA argument in a call to set_image_pixels (see below). */ public extern magick_pixel COLOR; ! /* Operations to create, read and write an image. The create_image function ! creates a new image, given an INFO tuple of the form (WIDTH, HEIGHT, DEPTH, ! MATTE, MAGICK), where (WIDTH, HEIGHT) denotes the dimensions of the image, ! DEPTH is the bit depth of the color values (usually 8 or 16), MATTE is a ! Bool value indicating whether the image has an alpha channel, and MAGICK is ! a string naming one of the image formats understood by ImageMagick. All ! fields of the INFO tuple are optional; suitable defaults will be provided ! for fields which are omitted. The clone_image function creates an exact copy of the given image. The read_image function reads an image from the given source, which may ! also include a format prefix (such as "rgb:file.rgb") or indicate a special builtin image object (such as "logo:" or "xc:white"); see ImageMagick(1) ! for details. Additional image properties may optionally be specified in the ! INFO argument, which has the same form as for create_image. (Note that for ! raw image data you will have to specify at least the image format and ! dimensions in the INFO tuple.) The write_image function writes the given image to the given target, designated by a name in the same syntax as for read_image. */ ! public extern create_image INFO, clone_image IMG; public extern read_image NAME INFO, write_image NAME IMG; /* Convert an image to a "blob" ("binary large object", represented as a byte string), and vice versa. This is useful, e.g., if an image is to be stored ! in a database, or if it is to be manipulated as raw data. The desired ! target format can be indicated with the MAGICK parameter of image_to_blob; ! you only have to specify this if the output blob should have a different ! format than the input image, otherwise just use () for this parameter. The ! blob_to_image function expects an INFO structure like the one passed to ! create_image and read_image, to specify image properties which cannot be ! deduced from the blob itself; this is necessary, e.g., if the blob is just ! raw RGB data. */ public extern image_to_blob MAGICK IMG, blob_to_image BLOB INFO; /* Retrieve the attributes of an image. The image_info function returns the ! attributes of an image encoded as an INFO tuple of the form (WIDTH, HEIGHT, ! DEPTH, MATTE, MAGICK). */ public extern image_info IMG; --- 59,115 ---- the range 0..0xffff; the alpha value is optional and is assumed to be 0xffff if it is missing. The function also packs a list of such values into ! a single byte string. The returned value can be passed as the PIXELS ! parameter of create_image and set_image_pixels. */ public extern magick_pixel COLOR; ! /* Operations to create, read and write an image. ! ! The create_image function creates a new image, given an INFO tuple of the ! form (WIDTH, HEIGHT, DEPTH, MATTE, MAGICK), where (WIDTH, HEIGHT) denotes ! the dimensions of the image, DEPTH is the bit depth of the color values ! (usually 8 or 16), MATTE is 1 if the image has an alpha channel and 0 ! otherwise, and MAGICK is a string naming one of the image formats ! understood by ImageMagick (such as EPS, GIF, RGB, etc.). ! ! Only the first two fields specifying the dimensions of the image are ! mandatory, the remaining fields will be filled with suitable defaults if ! they are omitted. The image will be created with the pixels initialized ! from the given PIXELS argument, a byte string of RGBA values representing ! either a single pixel or a pixel sequence whose length matches the ! dimensions of the image. The clone_image function creates an exact copy of the given image. The read_image function reads an image from the given source, which may ! also include a format prefix (such as "rgb:file") or indicate a special builtin image object (such as "logo:" or "xc:white"); see ImageMagick(1) ! for details. Additional image properties may be specified in the INFO ! argument, which has the same form as for create_image. For read_image, all ! fields in the INFO structure are optional, but note that for raw image data ! (e.g., RGB or RGBA) you will have to specify at least the dimensions of the ! image. The write_image function writes the given image to the given target, designated by a name in the same syntax as for read_image. */ ! public extern create_image INFO PIXELS, clone_image IMG; public extern read_image NAME INFO, write_image NAME IMG; /* Convert an image to a "blob" ("binary large object", represented as a byte string), and vice versa. This is useful, e.g., if an image is to be stored ! in a database, or if it is to be manipulated as raw data. The MAGICK ! parameter of image_to_blob can be used to indicate the desired target ! format; if it is () then the format of the image is used as the target ! format. The blob_to_image function takes an INFO structure like the one ! passed to create_image and read_image, to specify image properties which ! cannot be deduced from the blob itself; this is necessary, e.g., if the ! blob is just raw RGB data. */ public extern image_to_blob MAGICK IMG, blob_to_image BLOB INFO; /* Retrieve the attributes of an image. The image_info function returns the ! attributes of an image, encoded as an INFO tuple of the form (WIDTH, ! HEIGHT, DEPTH, MATTE, MAGICK). */ public extern image_info IMG; *************** *** 137,139 **** public extern get_image_pixels IMG P DIM; ! public extern set_image_pixels IMG P DIM DATA; --- 144,146 ---- public extern get_image_pixels IMG P DIM; ! public extern set_image_pixels IMG P DIM PIXELS; |