yorick-z/0000755000175000017500000000000010743144720012511 5ustar thibautthibautyorick-z/Makefile0000644000175000017500000000447410313362417014160 0ustar thibautthibaut# Makefile for yorick-z package # $Id: Makefile,v 1.1.1.1 2005/09/18 22:07:11 dhmunro Exp $ # run configure script to create Makeyorz and fill in following macros Y_MAKEDIR= Y_EXE= Y_EXE_PKGS= Y_EXE_HOME= Y_EXE_SITE= # ----------------------------------------------------- optimization flags COPT=$(COPT_DEFAULT) TGT=$(DEFAULT_TGT) # ------------------------------------------------ macros for this package PKG_NAME=yorz # change to give TGT=exe executable a name other than yorick PKG_EXENAME=yorick # Makeyorz defines PKG_I, OBJS, PKG_DEPLIBS, PKG_I_START, and *_INC macros include ./Makeyorz # list of additional package names you want in PKG_EXENAME # (typically Y_EXE_PKGS should be first here) EXTRA_PKGS=$(Y_EXE_PKGS) # list of additional files for clean PKG_CLEAN=test*.mpg test*.jpg test*.png cfg* yorz.doc # set compiler or loader flags specific to this package PKG_CFLAGS= PKG_LDFLAGS= # executable install directory Y_BINDIR=$(Y_HOME)/bin # -------------------------------- standard targets and rules (in Makepkg) # set macros Makepkg uses in target and dependency names # DLL_TARGETS, LIB_TARGETS, EXE_TARGETS # are any additional targets (defined below) prerequisite to # the plugin library, archive library, and executable, respectively PKG_I_DEPS=$(PKG_I) Y_DISTMAKE=distmake ALL_TARGETS=yorz.doc include $(Y_MAKEDIR)/Make.cfg include $(Y_MAKEDIR)/Makepkg include $(Y_MAKEDIR)/Make$(TGT) # override macros Makepkg sets for rules and other macros # Y_HOME and Y_SITE in Make.cfg may not be correct (e.g.- relocatable) Y_HOME=$(Y_EXE_HOME) Y_SITE=$(Y_EXE_SITE) # reduce chance of yorick-1.5 corrupting this Makefile MAKE_TEMPLATE = /usr/lib/yorick/1.5/protect-against-1.5 # ------------------------------------- targets and rules for this package ypng.o: spng.h spng.o: spng.c spng.h $(CC) $(CPPFLAGS) $(CFLAGS) $(PNG_INC) -c spng.c yzlib.o: yzlib.c $(CC) $(CPPFLAGS) $(CFLAGS) $(ZLIB_INC) -c yzlib.c yjpeg.o: yjpeg.c $(CC) $(CPPFLAGS) $(CFLAGS) $(JPEG_INC) -c yjpeg.c ympeg.o: ympeg.c $(YAVCODEC_H) $(CC) $(CPPFLAGS) $(CFLAGS) $(AVCODEC_INC) -c ympeg.c yorz.doc: $(PKG_I) $(Y_EXE) -batch ./maked.i $(PKG_I) install:: yorz.doc $(YNSTALL) yorz.doc "$(Y_SITE)/doc" uninstall:: rm -f "$(Y_SITE)/doc/yorz.doc" distclean:: rm -f Makeyorz yorz.i # -------------------------------------------------------- end of Makefile yorick-z/maked.i0000644000175000017500000000104710313362417013744 0ustar thibautthibaut/* * $Id: maked.i,v 1.1.1.1 2005/09/18 22:07:11 dhmunro Exp $ * make .doc files for yorz package */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #include "mkdoc.i" list = get_argv(); if (numberof(list) < 2) { write, "WARNING no .i documentation files specfied on command line"; } else { mkdoc, list(2:0), "yorz.doc"; write, "DOCUMENT comments written to yorz.doc"; } quit; yorick-z/ypng.c0000644000175000017500000002130210313362414013623 0ustar thibautthibaut/* * $Id: ypng.c,v 1.1.1.1 2005/09/18 22:07:08 dhmunro Exp $ * png interface for yorick */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #include "spng.h" #include "pstdlib.h" #include "ydata.h" #include "yio.h" extern void Y__png_read(int nArgs); extern void Y__png_write(int nArgs); /* for simage or cimage */ static void *ypng_imalloc(int depth, int nchan, int width, int height); static void ypng_ifree(void *image); /* for palette, alpha */ static void *ypng_cmalloc(int nchan, int npal); static void ypng_cfree(void *palette); /* for keytxt array of text pointers */ static void *ypng_pmalloc(int ntxt); static void ypng_pfree(void *keytxt); /* for text strings keytxt[i], purpose, punit */ static void *ypng_tmalloc(int nbytes); static void ypng_tfree(void *text); /* for internal scratch space */ static void *ypng_smalloc(unsigned long nbytes); static void ypng_sfree(void *scratch); static sp_memops ypng_memops = { ypng_imalloc, ypng_ifree, ypng_cmalloc, ypng_cfree, ypng_pmalloc, ypng_pfree, ypng_tmalloc, ypng_tfree, ypng_smalloc, ypng_sfree }; /* infopp is pointer info[9]: * info[0] = info.palette (char) * info[1] = info.alpha (char) or * info[2] = * info[3] = * info[4] = * info[5] = * info[6] = * info[7] = * info[8] = * dnwh[8]: * dnwh[0] = info.depth; * dnwh[1] = info.nchan; * dnwh[2] = info.width; * dnwh[3] = info.height; * dnwh[4] = info.npal; * dnwh[5] = info.ntxt; * dnwh[6] = info.alpha!=0 * dnwh[7] = info.nwarn; */ void Y__png_read(int nArgs) { /* do not bother to check arguments here -- done in interpreted code */ char *filename = YGetString(sp-4); long *dnwh = YGet_L(sp-3,0,0); void **infop = YGet_P(sp-2,0,0); void **imagep = YGet_P(sp-1,0,0); char **emsg = YGet_Q(sp-0,0,0); sp_info info; char *file = filename? p_native(filename) : 0; int rslt = file? sp_read(file, &ypng_memops, &info) : 0; if (file) p_free(file); dnwh[6] = info.nwarn; if (rslt || info.nwarn) emsg[0] = p_strcpy(info.msg); if (rslt) { PushIntValue(rslt); } else { int i; imagep[0] = (info.depth>8)? (void *)info.simage : (void *)info.cimage; dnwh[0] = info.depth; dnwh[1] = info.nchan; dnwh[2] = info.width; dnwh[3] = info.height; dnwh[4] = info.npal; dnwh[5] = info.ntxt; dnwh[6] = (info.alpha != 0); dnwh[7] = info.nwarn; infop[0] = info.palette; infop[1] = info.alpha; if ((info.colors & SP_TRNS) && !info.alpha) { Array *a = NewArray(&longStruct, ynew_dim((info.nchan>2)? 3L : 1L, 0)); long *trns = a->value.l; infop[1] = trns; trns[0] = info.trns[0]; if (info.nchan > 2) { trns[1] = info.trns[1]; trns[2] = info.trns[2]; } } if (info.colors & SP_BKGD) { Array *a = NewArray(&longStruct, ynew_dim((info.nchan>2)? 3L : 1L, 0)); long *bkgd = a->value.l; infop[2] = bkgd; bkgd[0] = info.bkgd[0]; if (info.nchan > 2) { bkgd[1] = info.bkgd[1]; bkgd[2] = info.bkgd[2]; } } if (info.x0 != info.x1) { Array *a = NewArray(&doubleStruct, ynew_dim(8L, 0)); double *pcal = a->value.d; infop[3] = pcal; pcal[0] = (double)info.x0; pcal[1] = (double)info.x1; pcal[2] = (double)info.mx; pcal[3] = (double)info.eqtype; pcal[4] = info.p[0]; pcal[5] = info.p[1]; pcal[6] = info.p[2]; pcal[7] = info.p[3]; if (info.purpose || info.punit) { Array *a = NewArray(&stringStruct, ynew_dim(2L, 0)); char **pcal2 = a->value.q; infop[4] = pcal2; pcal2[0] = info.purpose; pcal2[1] = info.punit; } } if (info.xpix_sz && info.ypix_sz) { Array *a = NewArray(&doubleStruct, ynew_dim(3L, 0)); double *scal = a->value.d; infop[5] = scal; scal[0] = info.xpix_sz; scal[1] = info.ypix_sz; scal[2] = (double)info.sunit; } if (info.n_xpix && info.n_ypix) { Array *a = NewArray(&longStruct, ynew_dim(3L, 0)); long *phys = a->value.l; infop[6] = phys; phys[0] = info.n_xpix; phys[1] = info.n_ypix; phys[2] = info.per_meter; } infop[7] = info.keytxt; if (info.itime[2]) { Array *a = NewArray(&longStruct, ynew_dim(6L, 0)); long *time = a->value.l; infop[8] = time; for (i=0 ; i<6 ; i++) time[i] = info.itime[i]; } PushIntValue(0); } } void Y__png_write(int nArgs) { /* do not bother to check arguments here -- done in interpreted code */ char *filename = YGetString(sp-4); long *dnwh = YGet_L(sp-3,0,0); void **infop = YGet_P(sp-2,0,0); void *image = *YGet_P(sp-1,0,0); char **emsg = YGet_Q(sp-0,0,0); char *file; int rslt; unsigned char *palette = (dnwh[4]>0 && dnwh[4]<=256)? infop[0] : 0; unsigned char *alpha = (palette && dnwh[6])? infop[1] : 0; unsigned long *trns = dnwh[6]? 0 : infop[1]; unsigned long *bkgd = infop[2]; double *pcal = infop[3]; char **pcal2 = infop[4]; double *scal = infop[5]; long *phys = infop[6]; char **keytxt = infop[7]; long *time = infop[8]; int depth = dnwh[0]; int nchan = dnwh[1]; int width = dnwh[2]; int height = dnwh[3]; int npal = palette? dnwh[4] : 0; int ntxt = dnwh[5]; sp_info info; sp_init(&info); if (depth > 8) info.simage = image; else info.cimage = image; info.depth = depth; info.nchan = nchan; info.width = width; info.height = height; info.npal = npal; info.palette = palette; info.alpha = alpha; if (trns) { info.colors |= SP_TRNS; info.trns[0] = trns[0]; if (nchan > 2) info.trns[1] = trns[1], info.trns[2] = trns[2]; else info.trns[1] = info.trns[2] = trns[0]; } if (bkgd) { info.colors |= SP_BKGD; info.bkgd[0] = bkgd[0]; if (nchan > 2) info.bkgd[1] = bkgd[1], info.bkgd[2] = bkgd[2]; else info.bkgd[1] = info.bkgd[2] = bkgd[0]; } if (pcal && pcal[0]!=pcal[1]) { info.x0 = (int)pcal[0]; info.x1 = (int)pcal[1]; info.mx = (int)pcal[2]; /* unused? */ info.eqtype = (int)pcal[3]; info.p[0] = pcal[4]; info.p[1] = pcal[5]; info.p[2] = pcal[6]; info.p[3] = pcal[7]; if (pcal2) { info.purpose = pcal2[0]; info.punit = pcal2[1]; } } if (scal) { info.xpix_sz = scal[0]; info.ypix_sz = scal[1]; info.sunit = (int)scal[2]; } if (phys) { info.n_xpix = (int)phys[0]; info.n_ypix = (int)phys[1]; info.per_meter = (phys[2]!=0); } if (keytxt && ntxt) { info.ntxt = ntxt; info.keytxt = keytxt; } if (time) { int i; for (i=0 ; i<6 ; i++) info.itime[i] = (short)time[i]; } file = p_native(filename); rslt = sp_write(filename, &ypng_memops, &info); p_free(file); dnwh[7] = info.nwarn; if (rslt || info.nwarn) emsg[0] = p_strcpy(info.msg); PushIntValue(rslt); } /* for simage or cimage */ static void * ypng_imalloc(int depth, int nchan, int width, int height) { Array *a; Dimension *d = ynew_dim((long)height, NewDimension((long)width, 1L, (nchan==1)? 0 : NewDimension((long)nchan, 1L, 0))); if (depth <= 8) { a = NewArray(&charStruct, d); return a->value.c; } else { a = NewArray(&shortStruct, d); return a->value.s; } } static void ypng_ifree(void *image) { Array *a = Pointee(image); Unref(a); } /* for palette, alpha */ static void * ypng_cmalloc(int nchan, int npal) { Array *a; if (nchan==1) a = NewArray(&charStruct, ynew_dim((long)npal, 0)); else a = NewArray(&charStruct, ynew_dim((long)npal, NewDimension(3L, 1L, 0))); return a->value.c; } static void ypng_cfree(void *palette) { Array *a = Pointee(palette); Unref(a); } /* for keytxt array of text pointers */ static void * ypng_pmalloc(int ntxt) { Array *a = NewArray(&stringStruct, ynew_dim((long)(ntxt+1)/2, NewDimension(2L, 1L, 0))); return a->value.q; } static void ypng_pfree(void *keytxt) { Array *a = Pointee(keytxt); Unref(a); } /* for text strings keytxt[i], purpose, punit */ static void * ypng_tmalloc(int nbytes) { return p_malloc(nbytes); } static void ypng_tfree(void *text) { p_free(text); } /* for internal scratch space */ static void * ypng_smalloc(unsigned long nbytes) { return p_malloc(nbytes); } static void ypng_sfree(void *scratch) { p_free(scratch); } yorick-z/spng.c0000644000175000017500000005074210313362416013631 0ustar thibautthibaut/* * $Id: spng.c,v 1.1.1.1 2005/09/18 22:07:10 dhmunro Exp $ * simplified png interface, directed to scientific data storage */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #include #include #include #include "png.h" #include "spng.h" /*------------------------------------------------------------------------*/ sp_info * sp_init(sp_info *info) { info->depth = info->nchan = info->width = info->height = 0; info->cimage = 0; info->simage = 0; info->npal = info->colors = 0; info->palette = info->alpha = 0; info->trns[0] = info->trns[1] = info->trns[2] = 0; info->bkgd[0] = info->bkgd[1] = info->bkgd[2] = 0; info->n_xpix = info->n_ypix = info->sunit = info->per_meter = 0; info->xpix_sz = info->ypix_sz = 0.0; info->purpose = info->punit = 0; info->eqtype = info->x0 = info->x1 = info->mx = 0; info->p[0] = info->p[1] = info->p[2] = info->p[3] = 0.0; info->ntxt = 0; info->keytxt = 0; info->itime[0] = info->itime[1] = info->itime[2] = info->itime[3] = info->itime[4] = info->itime[5] = 0; info->nerrs = info->nwarn = 0; info->msg[0] = '\0'; return info; } void sp_free(sp_info *info, sp_memops *memops) { if (info->cimage) { if (memops && memops->ifree) memops->ifree(info->cimage); else free(info->cimage); info->cimage = 0; } if (info->simage) { if (memops && memops->ifree) memops->ifree(info->simage); else free(info->simage); info->simage = 0; } if (info->palette) { if (memops && memops->cfree) memops->cfree(info->palette); else free(info->palette); info->palette = 0; } if (info->alpha) { if (memops && memops->cfree) memops->cfree(info->alpha); else free(info->alpha); info->alpha = 0; } if (info->purpose) { if (memops && memops->tfree) memops->tfree(info->purpose); else free(info->purpose); info->purpose = 0; } if (info->punit) { if (memops && memops->tfree) memops->tfree(info->punit); else free(info->punit); info->punit = 0; } if (info->keytxt) { int i, n = 2*info->ntxt; for (i=0 ; itfree) memops->tfree(info->keytxt[i]); else free(info->keytxt[i]); info->keytxt[i] = 0; } if (memops && memops->pfree) memops->pfree(info->keytxt); else free(info->keytxt); info->keytxt = 0; } } /*------------------------------------------------------------------------*/ typedef struct spng_id spng_id; struct spng_id { spng_id *id; png_structp p; png_infop pi; sp_memops *memops; sp_info *info; }; static void spng_error(png_structp p, png_const_charp msg); static void spng_warning(png_structp p, png_const_charp msg); static png_voidp spng_malloc(png_structp p, png_size_t nbytes); static void spng_free(png_structp p, png_voidp ptr); /*------------------------------------------------------------------------*/ int sp_read(const char *filename, sp_memops *memops, sp_info *info) { spng_id id; FILE *f = 0; png_structp p = 0; png_infop pi = 0; png_voidp (*spx_malloc)(png_structp p, png_size_t nbytes) = 0; void (*spx_free)(png_structp p, png_voidp ptr) = 0; png_bytep *rows = 0; png_color_8p sbit = 0; if (memops && memops->smalloc && memops->sfree) { spx_malloc = spng_malloc; spx_free = spng_free; } id.id = &id; id.p = 0; id.pi = 0; id.memops = memops; id.info = info; sp_init(info); f = fopen(filename, "rb"); if (!f) return 1; id.p = p = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, &id, spng_error, spng_warning, &id, spx_malloc, spx_free); if (!p) { fclose(f); return 2; } if (setjmp(png_jmpbuf(p))) { if (rows) { if (!memops || !memops->sfree) free(rows); else memops->sfree(rows); } png_destroy_read_struct(&p, &pi, 0); fclose(f); sp_free(info, memops); return 3; } id.pi = pi = png_create_info_struct(p); if (!pi) spng_error(p, "png_create_info_struct failed"); png_init_io(p, f); png_read_info(p, pi); { png_uint_32 w, h; int d, ctype; png_get_IHDR(p, pi, &w, &h, &d, &ctype, 0,0,0); info->width = w; info->height = h; info->depth = d; if (ctype == PNG_COLOR_TYPE_PALETTE) info->nchan = 0; else if (ctype == PNG_COLOR_TYPE_GRAY) info->nchan = 1; else if (ctype == PNG_COLOR_TYPE_GRAY_ALPHA) info->nchan = 2; else if (ctype == PNG_COLOR_TYPE_RGB) info->nchan = 3; else if (ctype == PNG_COLOR_TYPE_RGB_ALPHA) info->nchan = 4; else spng_error(p, "unknown PNG_COLOR_TYPE in png file"); } if (!info->nchan || info->nchan>=3) { int npal, i; png_colorp palette; if (png_get_PLTE(p, pi, &palette, &npal)) { info->npal = npal; if (npal > 0) { int ntrans; png_bytep trans; png_color_16p tvals; if (!memops || !memops->cmalloc) info->palette = malloc(3*npal); else info->palette = memops->cmalloc(3, npal); if (!info->palette) spng_error(p, "spng failed to malloc palette"); for (i=0 ; ipalette[3*i ] = palette[i].red; info->palette[3*i+1] = palette[i].green; info->palette[3*i+2] = palette[i].blue; } if (!info->nchan && png_get_tRNS(p, pi, &trans, &ntrans, &tvals)) { if (ntrans > npal) ntrans = npal; if (!memops || !memops->cmalloc) info->alpha = malloc(npal); else info->alpha = memops->cmalloc(1, npal); if (!info->alpha) spng_error(p, "spng failed to malloc alpha"); for (i=0 ; ialpha[i] = trans[i]; for ( ; ialpha[i] = 255; } } } } if (info->nchan==1 || info->nchan==3) { int ntrans; png_bytep trans; png_color_16p tvals; if (png_get_tRNS(p, pi, &trans, &ntrans, &tvals)) { if (info->nchan == 1) { info->trns[0] = info->trns[1] = info->trns[2] = tvals->gray; } else { info->trns[0] = tvals->red; info->trns[1] = tvals->green; info->trns[2] = tvals->blue; } info->colors |= SP_TRNS; } } if (info->nchan==1) { if (png_get_sBIT(p, pi, &sbit) && sbit->graydepth) info->depth = sbit->gray; else sbit = 0; } if (!info->nchan) info->nchan = 1; { png_color_16p bg; if (png_get_bKGD(p, pi, &bg)) { if (info->nchan > 2) { info->bkgd[0] = bg->red; info->bkgd[1] = bg->green; info->bkgd[2] = bg->blue; } else if (info->palette) { info->bkgd[0] = bg->index; info->bkgd[1] = info->bkgd[2] = 0; } else { info->bkgd[0] = info->bkgd[1] = info->bkgd[2] = bg->gray; } info->colors |= SP_BKGD; } } { png_uint_32 xpx, ypx; int unit; if (png_get_pHYs(p, pi, &xpx, &ypx, &unit)) { info->n_xpix = xpx; info->n_ypix = ypx; info->per_meter = (unit==PNG_RESOLUTION_METER); } } { int sunit; if (png_get_sCAL(p, pi, &sunit, &info->xpix_sz, &info->ypix_sz)) { if (sunit == PNG_SCALE_METER) info->sunit = SP_METERS; else if (sunit == PNG_SCALE_RADIAN) info->sunit = SP_RADIANS; else info->sunit = SP_UNKNOWN; } } { png_charp key, unit; png_charpp params; png_int_32 x0, x1; int type, nparams; if (png_get_pCAL(p, pi, &key, &x0, &x1, &type, &nparams, &unit, ¶ms)) { long lenk, lenu; char *pend; if (nparams<2 || x0==x1) spng_error(p, "illegal pCAL values in png"); if (type == PNG_EQUATION_LINEAR) info->eqtype = SP_LINEAR; else if (type == PNG_EQUATION_BASE_E) info->eqtype = SP_EXP; else if (type == PNG_EQUATION_ARBITRARY) info->eqtype = SP_POW; else if (type == PNG_EQUATION_HYPERBOLIC) info->eqtype = SP_SINH; else spng_error(p, "unknown pCAL equation type in png"); info->x0 = x0; info->x1 = x1; info->mx = (1<depth) - 1; info->p[0] = strtod(params[0], &pend); info->p[1] = strtod(params[1], &pend); info->p[2] = (nparams>2)? strtod(params[2], &pend) : 0.0; info->p[3] = (nparams>3)? strtod(params[3], &pend) : 0.0; lenk = key? strlen(key) : 0; lenu = unit? strlen(unit) : 0; if (memops->tmalloc) { if (lenk) info->purpose = memops->tmalloc(lenk+1); if (lenu) info->punit = memops->tmalloc(lenu+1); } else { if (lenk) info->purpose = malloc(lenk+1); if (lenu) info->punit = malloc(lenu+1); } if (key && info->purpose) strcpy(info->purpose, key); if (unit && info->punit) strcpy(info->punit, unit); } } { long i, rowbytes = info->nchan*info->width, nrows = info->height; unsigned char *image; if (info->depth < 8) { png_set_packing(p); /* one pixel per byte */ } else if (info->depth > 8) { short endian = 1; char *little_endian = (char *)&endian; if (little_endian[0]) png_set_swap(p); rowbytes += rowbytes; } if (sbit) png_set_shift(p, sbit); png_read_update_info(p, pi); if (png_get_rowbytes(p, pi) != rowbytes) spng_error(p, "unexpected number of bytes in image rows"); if (!memops || !memops->imalloc) image = malloc(rowbytes*nrows); else image = memops->imalloc(info->depth>8? 16 : 8, info->nchan, info->width, info->height); if (!image) spng_error(p, "spng failed to malloc image"); if (info->depth>8) info->simage = (unsigned short *)image; else info->cimage = image; if (!memops || !memops->smalloc) rows = malloc(sizeof(png_bytep)*nrows); else rows = memops->smalloc(sizeof(png_bytep)*nrows); if (!rows) spng_error(p, "spng failed to malloc rows"); for (i=0 ; isfree) free(rows); else memops->sfree(rows); rows = 0; } png_read_end(p, pi); { png_timep time; if (png_get_tIME(p, pi, &time)) { info->itime[0] = time->year; info->itime[1] = time->month; info->itime[2] = time->day; info->itime[3] = time->hour; info->itime[4] = time->minute; info->itime[5] = time->second; } } { png_textp ptext; int i, ntxt; long len; info->ntxt = png_get_text(p, pi, &ptext, &ntxt); if (ntxt > 0) { if (!memops->pmalloc) info->keytxt = malloc(sizeof(char*)*(ntxt+ntxt)); else info->keytxt = memops->pmalloc(ntxt+ntxt); if (!info->keytxt) spng_error(p, "spng failed to malloc comments"); for (i=0 ; ikeytxt[i+i] = info->keytxt[i+i+1] = 0; for (i=0 ; i 0) { info->keytxt[i+i] = memops->tmalloc? memops->tmalloc(len+1) : malloc(len+1); info->keytxt[i+i][0] = '\0'; if (info->keytxt[i+i]) strncat(info->keytxt[i+i], ptext[i].key, len); } len = ptext[i].text? ptext[i].text_length : 0; if (len > 0) { info->keytxt[i+i+1] = memops->tmalloc? memops->tmalloc(len+1) : malloc(len+1); info->keytxt[i+i+1][0] = '\0'; if (info->keytxt[i+i+1]) strncat(info->keytxt[i+i+1], ptext[i].text, len); } } } } png_destroy_read_struct(&p, &pi, 0); fclose(f); return 0; } /*------------------------------------------------------------------------*/ int sp_write(const char *filename, sp_memops *memops, sp_info *info) { spng_id id; FILE *f = 0; png_structp p = 0; png_infop pi = 0; int ctype, nchan = info->nchan, depth = info->depth; int width = info->width, height = info->height; int npal = info->palette? info->npal : 0; png_voidp (*spx_malloc)(png_structp p, png_size_t nbytes) = 0; void (*spx_free)(png_structp p, png_voidp ptr) = 0; png_bytep *rows = 0; png_color_8 sbit; int do_sbit = 0; if (nchan==1) ctype = PNG_COLOR_TYPE_GRAY; else if (nchan==2) ctype = PNG_COLOR_TYPE_GRAY_ALPHA; else if (nchan==3) ctype = PNG_COLOR_TYPE_RGB; else if (nchan==4) ctype = PNG_COLOR_TYPE_RGB_ALPHA; else ctype = 0; if (nchan==1 && npal>0) { ctype = PNG_COLOR_TYPE_PALETTE; if (depth > 8) npal = -1; } else if (npal && nchan==2) { npal = -1; } /* cannot store images with alpha channel at depth 1, 2, or 4 */ if ((nchan==2 || nchan>3) && depth<8) depth = 8; if ((depth>8)? (info->simage==0) : (info->cimage==0)) depth = 0; if (memops && memops->smalloc && memops->sfree) { spx_malloc = spng_malloc; spx_free = spng_free; } info->nerrs = info->nwarn = 0; info->msg[0] = '\0'; id.id = &id; id.p = 0; id.pi = 0; id.memops = memops; id.info = info; f = fopen(filename, "wb"); if (!f || nchan<1 || nchan>4 || width<1 || height<1 || depth<1 || depth>16 || (nchan!=1 && ((depth-1)&depth)) || npal<0 || npal>PNG_MAX_PALETTE_LENGTH) return 1; id.p = p = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, &id, spng_error, spng_warning, &id, spx_malloc, spx_free); if (!p) { fclose(f); return 2; } if (setjmp(png_jmpbuf(p))) { if (rows) { if (!memops || !memops->sfree) free(rows); else memops->sfree(rows); } png_destroy_read_struct(&p, &pi, 0); fclose(f); return 3; } id.pi = pi = png_create_info_struct(p); if (!pi) spng_error(p, "png_create_info_struct failed"); png_init_io(p, f); if ((depth-1) & depth) { do_sbit = !npal; sbit.gray = depth; if (sbit.gray > 8) depth = 16; else if (sbit.gray > 4) depth = 8; else depth = 4; } png_set_IHDR(p, pi, (png_uint_32)width, (png_uint_32)height, depth, ctype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if (npal > 0) { png_color ppal[PNG_MAX_PALETTE_LENGTH]; int i; for (i=0 ; ipalette[3*i ]; ppal[i].green = info->palette[3*i+1]; ppal[i].blue = info->palette[3*i+2]; } png_set_PLTE(p, pi, ppal, npal); if (nchan == 1) { if (info->alpha) { png_byte alpha[PNG_MAX_PALETTE_LENGTH]; for (i=0 ; ialpha[i]; png_set_tRNS(p, pi, alpha, npal, 0); } nchan = 0; } } /* trns is info->alpha for pseudocolor, illegal if aplha in pixel */ if ((info->colors & SP_TRNS) && (nchan==1 || nchan==3)) { /* transparent color values have same range as image pixel values */ png_color_16 tval; if (nchan == 3) { tval.red = info->trns[0]; tval.green = info->trns[1]; tval.blue = info->trns[2]; tval.gray = ((long)info->trns[0]+(long)info->trns[1]+(long)info->trns[2])/3; } else { tval.gray = tval.red = tval.green = tval.blue = info->trns[0]; } png_set_tRNS(p, pi, 0, 0, &tval); } if (!nchan) nchan = 1; if (do_sbit) png_set_sBIT(p, pi, &sbit); if (info->colors & SP_BKGD) { /* background color values have same range as image pixel values */ png_color_16 bg; if (nchan > 2) { bg.red = info->bkgd[0]; bg.green = info->bkgd[1]; bg.blue = info->bkgd[2]; bg.gray = ((long)info->bkgd[0]+(long)info->bkgd[1]+(long)info->bkgd[2])/3; } else if (npal > 0) { bg.index = info->bkgd[0]; bg.gray = bg.red = bg.green = bg.blue = 0; } else { bg.gray = bg.red = bg.green = bg.blue = info->bkgd[0]; bg.index = 0; } png_set_bKGD(p, pi, &bg); } if (info->n_xpix>0 && info->n_ypix>0) { png_set_pHYs(p, pi, (png_uint_32)info->n_xpix, (png_uint_32)info->n_ypix, (info->per_meter!=0)? PNG_RESOLUTION_METER:PNG_RESOLUTION_UNKNOWN); } if (info->xpix_sz>0.0 && info->ypix_sz>0.0) { int unit = PNG_SCALE_UNKNOWN; if (info->sunit == SP_METERS) unit = PNG_SCALE_METER; else if (info->sunit == SP_RADIANS) unit = PNG_SCALE_RADIAN; png_set_sCAL(p, pi, unit, info->xpix_sz, info->ypix_sz); } if ((info->x0 != info->x1) && info->p[1] && (info->eqtype==SP_LINEAR || info->eqtype==SP_EXP || info->eqtype==SP_POW || info->eqtype==SP_SINH) && (info->eqtype==SP_LINEAR || info->p[2])) { char p0[20], p1[20], p2[20], p3[20]; int type = PNG_EQUATION_LINEAR, np = 2; char *params[4]; params[0]=p0; params[1]=p1; params[2]=p2; params[3]=p3; if (info->eqtype == SP_EXP) type = PNG_EQUATION_BASE_E, np = 3; else if (info->eqtype == SP_POW) type = PNG_EQUATION_ARBITRARY, np = 3; else if (info->eqtype == SP_SINH) type = PNG_EQUATION_HYPERBOLIC, np = 4; sprintf(params[0], "%.10e", info->p[0]); sprintf(params[1], "%.10e", info->p[1]); if (np>2) sprintf(params[2], "%.10e", info->p[2]); if (np>3) sprintf(params[3], "%.10e", info->p[3]); png_set_pCAL(p, pi, info->purpose, (png_int_32)info->x0, (png_int_32)info->x1, type, np, info->punit, (png_charpp)params); } if (info->itime[1]) { static int mxday[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int year = info->itime[0]; int month = info->itime[1]; int day = info->itime[2]; int hour = info->itime[3]; int minute = info->itime[4]; int second = info->itime[5]; if (year>=0 && year<=9999 && month>=1 && month<=12 && day>=1 && day<=mxday[month-1] && hour>=0 && hour<=23 && minute>=0 && minute<=59 && second>=0 && second<=61 && (day!=29 || month!=2 || !(year%4))) { png_time tpng; if (year<60) year += 2000; else if (year<100) year += 1900; tpng.year = year; tpng.month = month; tpng.day = day; tpng.hour = hour; tpng.minute = minute; tpng.second = second; png_set_tIME(p, pi, &tpng); } } if (info->ntxt && info->keytxt) { png_size_t len; png_text ptext; char k[PNG_KEYWORD_MAX_LENGTH+1]; int i; for (i=0 ; intxt ; i++) { /* silently enforce strlen(key)<=PNG_KEYWORD_MAX_LENGTH */ k[0] = '\0'; if (info->keytxt[i+i]) strncat(k, info->keytxt[i+i], PNG_KEYWORD_MAX_LENGTH); len = info->keytxt[i+i+1]? strlen(info->keytxt[i+i+1]) : 0; ptext.compression = (len>1024)? PNG_TEXT_COMPRESSION_zTXt : PNG_TEXT_COMPRESSION_NONE; ptext.key = k; ptext.text = info->keytxt[i+i+1]; ptext.text_length = len; #ifdef PNG_iTXt_SUPPORTED ptext.itxt_length = 0; ptext.lang = 0; ptext.lang_key = 0; #endif png_set_text(p, pi, &ptext, 1); } } png_write_info(p, pi); { long i, rowbytes = nchan*width, nrows = height; unsigned char *image = info->cimage; if (depth < 8) png_set_packing(p); /* one pixel per byte */ if (depth > 8) { short endian = 1; char *little_endian = (char *)&endian; if (little_endian[0]) png_set_swap(p); rowbytes += rowbytes; image = (unsigned char *)info->simage; } if (do_sbit) png_set_shift(p, &sbit); if (!memops || !memops->smalloc) rows = malloc(sizeof(png_bytep)*nrows); else rows = memops->smalloc(sizeof(png_bytep)*nrows); if (!rows) spng_error(p, "spng failed to malloc rows"); for (i=0 ; isfree) free(rows); else memops->sfree(rows); rows = 0; } png_write_end(p, pi); png_destroy_write_struct(&p, &pi); fclose(f); return 0; } /*------------------------------------------------------------------------*/ static png_voidp spng_malloc(png_structp p, png_size_t nbytes) { spng_id *id = png_get_mem_ptr(p); if (id && id->id==id && id->memops->smalloc) { return id->memops->smalloc((unsigned long)nbytes); } else { return png_malloc_default(p, nbytes); } } static void spng_free(png_structp p, png_voidp ptr) { spng_id *id = png_get_mem_ptr(p); if (id && id->id==id && id->memops->sfree) { id->memops->sfree((void *)ptr); } else { png_free_default(p, ptr); } } static void spng_error(png_structp p, png_const_charp msg) { spng_id *id = png_get_error_ptr(p); if (id && id->id==id && id->info) { id->info->nerrs++; if (!id->info->msg[0]) strncat(id->info->msg, msg, 95); } longjmp(png_jmpbuf(p), 1); } static void spng_warning(png_structp p, png_const_charp msg) { spng_id *id = png_get_error_ptr(p); if (id && id->id==id && id->info) { if (!id->info->nerrs && !id->info->msg[0]) strncat(id->info->msg, msg, 95); id->info->nwarn++; } } /*------------------------------------------------------------------------*/ yorick-z/png.i0000644000175000017500000004702010731065646013460 0ustar thibautthibaut/* * $Id: png.i,v 1.3 2007/12/16 00:04:54 dhmunro Exp $ * yorick interface to libpng image compression (www.libpng.org) */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ if (!is_void(plug_in)) plug_in, "yorz"; func png2(name) /* DOCUMENT png2, name writes the picture in the current graphics window to the png file NAME, or to NAME+".png" is NAME does not end in ".png". SEE ALSO: png, jpeg, pdf, eps, hcps */ { if (strpart(name,-3:0)!=".png") name+= ".png"; png_write, name, rgb_read(); return name; } func png_read(filename, &depth, &nfo, type=, quiet=) /* DOCUMENT image = png_read(filename) * or image = png_read(filename, depth, nfo) * * Read png file FILENAME. The returned IMAGE is either an array * of char or short, unless type= is specified (see below). * The IMAGE may have a leading dimension of 2 if it is gray+alpha, * 3 if it is rgb, or 4 if it is rgba. * In the second form, DEPTH and NFO must be simple variable references. * NFO is set to a pointer array to descriptive information by png_read: * *nfo(1) = PLTE 3-by-N char array of palette rgb values * *nfo(2) = tRNS char array of alpha (opacity) values corresponding * to PLTE or single gray or rgb short value (transparent) * *nfo(3) = bKGD single gray or rgb short value * note that bKGD and the single value tRNS have the same * range and meaning as a pixel value, in particular, * for a pseudocolor image, they represent a palette index * *nfo(4) = pCAL [x0,x1,max,eqtype,p0,p1,p2,p3,...] physical pixel value * relation between pixel value and physical value * array of double values (see below for meaning) * *nfo(5) = pCAL [calibration_name, unit_name] string pair * *nfo(6) = sCAL [wide,high,sunit] physical scale of pixels as scanned * or printed, sunit 1.0 for meters or 2.0 for radians * *nfo(7) = pHYs long [n_xpix,n_ypix,per_meter] values * n_xpix,n_ypix are pixels per unit, * per_meter is 0 for aspect ratio only, 1 for meters * *nfo(8) = tEXt (or zTXt or iTXt) 2-by-N string array of (key,text) * *nfo(9) = tIME string value image modification time * any or all of these NFO values may be nil. The four character * designators (e.g. PLTE) are the png chunk names for the corresponding * information. * * pCAL array of doubles has following meaning: * max = 2^depth-1 * original = long( floor( (image(i)*(x1-x0)+long(max)/2) / max ) ) + x0 * image(i) = long( floor( ((original-x0)*max+long(x1-x0)/2) / (x1-x0) ) ) * eqtype = 0 physical = p0 + p1*original/(x1-x0) * eqtype = 1 physical = p0 + p1*exp(p2*original/(x1-x0)) * eqtype = 2 physical = p0 + p1*p2^(original/(x1-x0)) * eqtype = 3 physical = p0 + p1*sinh(p2*(original-p3)/(x1-x0)) * * If the type= keyword is non-nil and non-zero, the returned value * is as if png_scale(image, nfo, type=type), which scales the raw image * according to the information in pCAL, or is a no-op if pCAL does * not exist. * * SEE ALSO: png_write, png_scale */ { dnwh = array(long, 8); nfo = array(pointer, 9); image = &[]; emsg = string(0); rslt = _png_read(filename, dnwh, nfo, image, emsg); if (rslt) { if (rslt == 1) error, "unable to open "+filename; else if (rslt == 2) error, "PNG ERROR: png_create_read_struct_2 failed"; error, "PNG ERROR: "+emsg; } if (dnwh(8) && !quiet) { write, format="PNG %ld warnings: %s\n", dnwh(8), emsg; } depth = dnwh(1); if (is_void(type)) image = *image; else image = png_scale(*image, nfo, type=type); return image; } func png_write(filename, image, depth, nfo, palette=, alpha=, bkgd=, pcal=, pcals=, scal=, phys=, text=, time=, trns=, quiet=) /* DOCUMENT png_write, filename, image * or png_write, filename, image, depth, nfo * * Write png file FILENAME containing IMAGE at the specified DEPTH. * The default DEPTH is 8 bits. For grayscale IMAGE, 1<=DEPTH<=16, * otherwise depth is 8 or 16. If NFO is specified, it is an * array of pointers as described in the help for png_read. You can * optionally specify the same information as keywords: * palette=[[r0,g0,b0],[r1,g1,b1],...] * alpha=[a0,a1,...] if image is simple 2D and palette specified * trns=value if image is gray (no palette) * [r,g,b] if image is color * illegal if image has alpha channel * bkgd=value or [r,g,b] suggested background color * note that bkgd and trns have the same range and meaning as a * pixel value, in particular, for a pseudocolor, a palette index * pcal=[x0,x1,max,eqtype,p0,p1,p2,p3,...] * pcals=[calibration_name, unit_name] as for pCAL (see png_read) * scal=[wide,high,sunit] as for sCAL (see png_read) * phys=[n_xpix,n_ypix,per_meter] as for pHYs (see png_read) * text=[[key1,text1],[key1,text1],...] * recognized keys are: Title, Author, Description, Copyright, * Creation Time, Software, Disclaimer, Warning, Source (a device), * and Comment * time=string modification time (timestamp() is default) * When both NFO and keywords are supplied, the keywords override any * corresponding value in nfo. * * If IMAGE has a data type other than short or char, a default pCAL * will be supplied if it is a simple grayscale (2D) image. If DEPTH * is not supplied, it defaults to 8 if IMAGE is type char and/or if * a palette is supplied, or to 16 otherwise. * * SEE ALSO: png_read, png_map */ { /* eventually, do conversion and even select pcal automatically */ if (structof(image(1)+0) != long) error, "image must be converted to integer data type"; dnwh = array(long, 8); dims = dimsof(image); nchan = (dims(1)==2); if (dims(1)==3) nchan = dims(2); if (nchan<1 || nchan>4) error, "image must have 1-4 channels (gray, gray+A, RGB, or RGBA)"; dnwh(2) = nchan; dnwh(3:4) = dims(-1:0); if (structof(nfo)==pointer && numberof(nfo)==9) { if (is_void(palette)) eq_nocopy, palette, *nfo(1); if (nfo(2)) { if (nchan==1 && palette) { if (is_void(alpha)) eq_nocopy, alpha, *nfo(2); } else { if (is_void(trns)) eq_nocopy, trns, *nfo(2); } } if (is_void(bkgd)) eq_nocopy, bkgd, *nfo(3); if (is_void(pcal)) eq_nocopy, pcal, *nfo(4); if (is_void(pcals)) eq_nocopy, pcals, *nfo(5); if (is_void(scal)) eq_nocopy, scal, *nfo(6); if (is_void(phys)) eq_nocopy, phys, *nfo(7); if (is_void(text)) eq_nocopy, text, *nfo(8); if (is_void(time)) eq_nocopy, time, *nfo(9); } else if (!is_void(nfo)) { error, "illegal nfo format"; } nfo = array(pointer, 9); pseudo = (nchan==1 && !is_void(palette)); dep = 0; if (!is_void(pcal)) { mx = long(pcal(3)); if (mx>65535 || mx<1) error, "pcal(3) mx parameter too big or too small"; else if (mx > 255) dep = 16; else if (mx > 15) dep = 8; else if (mx > 3) dep = 4; else if (mx > 1) dep = 2; else dep = 1; x0 = long(pcal(1)); x1 = long(pcal(2)); eqtype = long(pcal(4)); p = double(pcal(5:8)); } istruct = structof(image); if (!depth) { if (dep) depth = (istruct==char)? min(dep,8) : dep; else if (istruct==char || pseudo) depth = 8; else depth = 16; } dnwh(1) = depth; /* eventually, this should pay attention to pcal */ if (depth > 8) { if (istruct != short) image = short(image); } else { if (istruct != char) image = char(image); } npal = 0; if (!is_void(palette)) { if (nchan==2) error, "palette illegal for gray+alpha (2 channel) image"; dims = dimsof(palette); if (!numberof(dims) || anyof(dims(1:2)!=[2,3]) || dims(3)>256 || max(palette)>255 || min(palette)<0 || structof(palette+0)!=long) error, "illegal palette format or length"; if (structof(palette)!=char) palette = char(palette); npal = dims(3); nfo(1) = &palette; } if (!is_void(alpha)) { if (nchan!=1 || !npal) error, "alpha illegal for non-pseudocolor image"; dims = dimsof(alpha); if (!numberof(dims) || dims(1)!=1 || max(alpha)>255 || min(alpha)<0 || structof(alpha+0)!=long) error, "illegal alpha format or length"; if (structof(alpha)!=char) alpha = char(alpha); dnwh(7) = 1; nfo(2) = α } if (!is_void(trns)) { if (nchan==2 || nchan==4) error, "trns illegal when image pixels have alpha channel"; else if (nchan==1 && npal) error, "trns illegal for pseudocolor image, use alpha="; else if (nchan==1 && numberof(trns)==1) trns = trns(1)(1,-:1:3); dims = dimsof(trns); if (!numberof(dims) || dims(1)!=1 || dims(2)!=3 || min(trns)<0 || structof(trns+0)!=long) error, "illegal trns format or length"; trns = long(trns); nfo(2) = &trns; } if (!is_void(bkgd)) { if (nchan < 3) bkgd = bkgd(1)(1,-:1:3); dims = dimsof(bkgd); if (!numberof(dims) || dims(1)!=1 || dims(2)!=3 || min(bkgd)<0 || structof(bkgd+0)!=long) error, "illegal bkgd format or length"; bkgd = long(bkgd); nfo(3) = &bkgd; } if (!is_void(pcal)) { pcal = double(pcal); dims = dimsof(pcal); if (!numberof(dims) || dims(1)!=1 || dims(2)!=8 || anyof(pcal(1:4)!=long(pcal(1:4)))) error, "illegal pcal format or length"; if (pcal(4)<1 || pcal(4)>4) error, "unknown eqtype in pcal"; nfo(4) = &pcal; } if (!is_void(pcals)) { dims = dimsof(pcals); if (!numberof(dims) || dims(1)!=1 || dims(2)!=2 || structof(pcals)!=string) error, "illegal pcals format or length"; nfo(5) = &pcals; } if (!is_void(scal)) { scal = double(scal); dims = dimsof(scal); if (!numberof(dims) || dims(1)!=1 || dims(2)!=3 || scal(3)!=long(scal(3))) error, "illegal scal format or length"; nfo(6) = &scal; } if (!is_void(phys)) { phys = phys+0; dims = dimsof(phys); if (!numberof(dims) || dims(1)!=1 || dims(2)!=3 || structof(phys)!=long || anyof(phys(1:2)<=0)) error, "illegal phys format or length"; nfo(7) = &phys; } ntxt = 0; if (!is_void(text)) { dims = dimsof(text); if (!numberof(dims) || dims(1)!=2 || dims(2)!=2 || structof(text)!=string) error, "illegal text or nfo(8) format or length"; ntxt = dims(3); nfo(8) = &text; } if (!is_void(time)) { time = time+0; dims = dimsof(time); if (!numberof(dims) || dims(1)!=1 || dims(2)!=6 || structof(time)!=long || anyof(time<0)) error, "illegal time format or length"; nfo(9) = &time; } dnwh(5) = npal; dnwh(6) = ntxt; emsg = string(0); rslt = _png_write(filename, dnwh, nfo, &image, emsg); if (rslt) { if (rslt == 1) error, "bad inputs or unable to create "+filename; else if (rslt == 2) error, "PNG ERROR: png_create_write_struct_2 failed"; error, "PNG ERROR: "+emsg; } if (dnwh(8) && !quiet) { write, format="PNG %ld warnings: %s\n", dnwh(8), emsg; } } func png_scale(image, nfo, type=) /* DOCUMENT image = png_scale(raw_image, nfo, type=type) * scales RAW_IMAGE to type TYPE (char, short, int, long, float, or * double, according to the pCAL information in NFO. The NFO * parameter may be either the array of pointers returned by * png_read, or an array of reals as for *nfo(4) (see png_read). * * SEE ALSO: png_map, png_read, png_write */ { if (structof(nfo) == pointer) nfo = *nfo(4); if (is_void(nfo)) return image; dx = nfo(2) - nfo(1); x0 = long(nfo(1)); x1 = long(nfo(2)); mx = long(nfo(3)); eq = long(nfo(4)); p = double(nfo(5:0)); if (eq<0 || eq>3) error, "unknown equation type"; sample = image(1); image = long(image); if (sizeof(sample) == 1) image &= ~0xff; else if (sizeof(sample) == 2) image &= ~0xffff; else if (anyof((image>mx) | (image<0))) error, "image out of scaling range"; if (mx<1 || mx>65535 || ((mx+1)&mx)) error, "max=2^depth-1 has impossible value"; if (x1 > x0) { x1 -= x0; } else if (x1 < x0) { /* adjust so that x1 > 0 in all cases */ x1 = x0 - x1; x0 -= x1; /* i.e.- original x1 */ image = mx - image; } else { error, "x0 == x1 is impossible scaling"; } /* here is formula from PNG Extensions document (x1>0): * d = image*(x1%mx); * image = image*(x1/mx) + d/mx + (d%mx + mx/2)/mx + x0; */ q = x1 / mx; r = x1 & mx; /* mx = 2^n - 1 */ if (r) { r *= image; r = r/mx + ((r&mx)+(mx>>1))/mx; } if (q) image *= q; image += r + x0; if (is_void(type)) { if (!eq && !p(1) && p(2)==dx) { if (x0>=0 && x1<256) type = char; else if (x0>-32768 && x1+x0<32768) type = short; else type = long; } else { type = double; } } sample = type(0); if (structof(sample+0) != long) { dx = 1./dx; if (!eq) image *= dx; else if (eq == 1) image = exp(p(3)*dx * image); else if (eq == 2) image = p(3) ^ (dx * image); else image = sinh(p(3)*dx * (image-p(4))); image = p(1) + p(2)*image; } return type(image); } func png_map(image, nfo) /* DOCUMENT image = png_map(full_image, nfo) * maps FULL_IMAGE to png-stored values, according to the * pCAL information in NFO. * The NFO parameter may be either the array of pointers as returned by * png_read, or an array of reals as for *nfo(4) (see png_read). * You can use png_pcal to compute an NFO mapping tailored to IMAGE. * * SEE ALSO: png_pcal, png_scale, png_read, png_write */ { if (!is_void(cmax)) image = min(image,cmax); if (!is_void(cmin)) image = max(image,cmin); if (structof(nfo) == pointer) nfo = *nfo(4); dx = nfo(2) - nfo(1); x0 = long(nfo(1)); x1 = long(nfo(2)); mx = long(nfo(3)); eq = long(nfo(4)); p = double(nfo(5:0)); if (eq<0 || eq>3) error, "unknown equation type"; if (x0 == x1) error, "x0 == x1 is impossible scaling"; if (mx<1 || mx>65535 || ((mx+1)&mx)) error, "max=2^depth-1 has impossible value"; if (eq || p(1) || p(2)!=dx) { /* pre-clip image to map inside interval [x0,x1] */ x = nfo(1:2); if (!eq) x /= dx; else if (eq == 1) x = exp(p(3)/dx * x); else if (eq == 2) x = p(3) ^ (x/dx); else image = sinh(p(3)/dx * (x-p(4))); x = p(1) + p(2)*x; image = min(max(x), max(min(x),image)); /* then convert image to integer values in interval [x0,x1] */ image = (image - p(1)) * (1./p(2)); if (!eq) image *= dx; else if (eq == 1) image = (dx/p(3)) * _png_log(image); else if (eq == 2) image = (dx/_png_log(p(3))) * _png_log(image); else image = (dx/p(3)) * asinh(image) + p(4); image = long(image); } if (x1 > x0) { x1 -= x0; } else { /* adjust so that x1 > 0 in all cases */ x1 = x0 - x1; x0 -= x1; /* i.e.- original x1 */ } image = min(x1, max(0,image-x0)); if (x1 <= 0xffff) image = (image*mx + (x1>>1)) / x1; else image = long((double(image)*mx + (x1>>1)) / x1); return (mx <= 255)? char(image) : short(image); } func png_pcal(image, depth, cmin=, cmax=, res=, log=) /* DOCUMENT pcal = png_pcal(image) * or pcal = png_pcal(image, depth) * * KEYWORDS: cmin=, cmax=, res=, log= * cmin, cmax clip image to these minimum and maximum values * res image "resolution", or minimum step size * log non-zero forces log map if image all positive * or all negative * * returns 8-element pCAL png mapping for IMAGE, appropriate for * use as pcal= keyword in png_write. The png_map function applies * pcal to produce the as-stored char or short array; the png_scale * function applies pcal to recreate the original IMAGE from the * as-stored array. * * There are three kinds of pCAL mappings: linear, log, and asinh. * Linear and log scales are familiar; the asinh scale is a modified * log scale that can be used for arrays that change sign: * * linear: image = a*stored + b * log: image = b * exp(a*stored) * asinh: image = b * sinh(a*(stored - mx/2)) * * You can specify a bit DEPTH for the stored array, which can be * between 2 and 16 inclusive. For bit depth 1, just threshhold * the image (image>const_thresh). By default, for integer IMAGE, * DEPTH is the smallest depth that covers the range of IMAGE values, * but never more than 16. For float or double IMAGE, the default * DEPTH is always 16. * * If IMAGE has any integer data type, the pCAL mapping will always * be linear; use IMAGE+0.0 if you want a log or asinh map. * * The png pCAL definition allows b<0 in the log scale, so it can * be used for image values that are either all positive or all * negative. In either case, the integer stored values take equal * ratio steps from the minimum to the maximum image values (or * cmin and cmax). For the linear scale, of course, each step in * the stored integer represents an constant increment in the image * value. The asinh scale is a logarithmic ratio scale for stored * values near 0 or mx (the maximum stored integer value), reverting * to a linear scale near the middle of its range where the image * value passes through zero. * * To get the asinh scale, you must specify the res= keyword: * You must specify the smallest step size for the asinh scale by * setting the res= keyword. For a log scale, the res= value will * replace the actual minimum array value or cmin value (or cmax if * image is all negative values), clipping any smaller absolute values. * If mx is large enough to cover the whole scale with the given res= * value in linear steps, a linear scale will be used. * * You can specify log=1 to force log scaling if image is all * positive or all negative. * * SEE ALSO: png_scale, png_write, png_read */ { sample = image(1); in = min(image); ix = max(image); if (!is_void(cmax)) { in = min(in, cmax); ix = min(ix, cmax); } if (!is_void(cmin)) { in = max(in, cmin); ix = max(ix, cmin); } if (depth && (depth<2 || depth>16)) error, "depth must be 2<=depth<=16 (for depth=1 just threshhold)"; if (structof(sample+0) == long) { x0 = long(in); x1 = long(ix); if (!depth) for (mx=2,depth=1 ; mx>x1-x0 ; mx<<1,depth++); mx = (1<=(ix-in)) { eq = 0; } else if (in*ix > 0.) { if (res && abs(res) 0.) in = abs(res); else ix = -abs(res); } lrat = _png_log(ix/in); if (in!=ix && (log || abs(lrat)>_png_log(32.))) { eq = 1; p = [0., in, lrat/mx, 0.]; } else { eq = 0; } } else { if (res) { eq = 3; /* sinh(0.5*p3)/sinh(p3/mx) = max(abs(x))/res * roughly (0.5-1/mx)*p3 = log(axmax/res) * know axmax/abs(res) > mx */ p4 = 0.5*mx; p = _png_eq3(p4, max(abs(in),abs(ix))/abs(res)); p2 = abs(res) / sinh(p); p3 = mx * p; p = [0., p2, p3, p4]; } else { eq = 0; } } if (!eq) p = [double(in), ((in==ix)? mx : double(ix-in)/mx), 0., 0.]; } return grow(double([x0, x1, mx, eq]), p); } func _png_eq3(a, b) { /* solve sinh(a*x)/sinh(x) = b for x assuming b>a>1 */ x = _png_log(b)/(a-1.); /* overestimate of root */ for (i=1,err=1. ; i<50 && err>1e-9 ; i++) { s = sinh(x); bs = b*s; y = a*x - asinh(bs); yp = a - b*sqrt((1.+s*s)/(1.+bs*bs)); if (yp <= 0.) error, "eq=3 root solve lost"; dx = y/yp; x -= dx; err = abs(dx)/x; } return x; } if (is_void(_png_log)) _png_log = log; extern _png_read; extern _png_write; yorick-z/configure0000755000175000017500000002632110734436141014425 0ustar thibautthibaut#!/bin/sh # $Id: configure,v 1.4 2007/12/26 11:34:57 thiebaut Exp $ echo "" echo "================ begin yorick-z configuration ====================" echo "" # note: ZLIB_INC, ZLIB_LIB, PNG_INC, PNG_LIB, JPEG_INC, JPEG_LIB, # AVCODEC_INC, AVCODEC_LIB # environment variables can be used to set detailed default values # --zlib=, --png=, --jpeg=, --avcodec= command line options are designed # for the simple case in which the library has been built in place from # its source distribution and NOT installed curdate=`date` cursystem=`uname -a` fatality=0 # should LD_LIBRARY_PATH, LIBPATH (AIX), LPATH, SHLIB_PATH (HPUX) be saved? yorick_exe="yorick" zlib_path= png_path= jpeg_path= av_path= av_dlopen="no" debug="no" use_a="no" for opt do case "$opt" in --debug) debug="yes" ;; --yorick=*) yorick_exe=`echo $opt | sed -e s/--yorick=//` ;; --zlib=*) zlib_path=`echo $opt | sed -e s/--zlib=//` ;; --png=*) png_path=`echo $opt | sed -e s/--png=//` ;; --jpeg=*) jpeg_path=`echo $opt | sed -e s/--jpeg=//` ;; --avcodec=*) av_path=`echo $opt | sed -e s/--avcodec=//` ;; --dl-avcodec) av_dlopen="yes" ;; --no-avcodec) av_dlopen="skip" ;; --a) use_a="yes" ;; *) cat <cfg.c <cfg.0 2>&1; then found="yes" else if test -n "$zlib_path"; then echo "WARNING: --zlib=$zlib_path DID NOT WORK, IS IT BUILT?" fi for p in $plist; do ZLIB_INC=-I$p/include ZLIB_LIB="-L$p/lib -lz" if $CC $CFLAGS $ZLIB_INC -o cfg cfg.c $ZLIB_LIB >cfg.1 2>&1; then found="yes" break fi done fi if test $found = no; then has_zlib=no echo "zlib: not found" ZLIB_INC= ZLIB_LIB= ILIST= OLIST= else has_zlib=yes echo "zlib: found" echo " ZLIB_INC=$ZLIB_INC" echo " ZLIB_LIB=$ZLIB_LIB" ZLIB_INC0=$ZLIB_INC ILIST=zlib.i OLIST=yzlib.o fi #------------------------------------------------------------------------ # find png header and library cat >cfg.c <cfg.2 2>&1; then found="yes" else if test -n "$png_path"; then echo "WARNING: --png=$png_path DID NOT WORK, IS IT BUILT?" fi for p in $plist; do PNG_INC=-I$p/include PNG_LIB="-L$p/lib -lpng" libs="$PNG_LIB $ZLIB_LIB -lm" if $CC $CFLAGS $PNG_INC $ZLIB_INC0 -o cfg cfg.c $libs >cfg.3 2>&1; then found="yes" break fi done fi if test $found = no; then has_png=no echo "png: not found" PNG_INC= PNG_LIB= else has_png=yes need_lm=yes echo "png: found" if test "$PNG_INC" != "$ZLIB_INC0"; then PNG_INC="$PNG_INC $ZLIB_INC0" fi echo " PNG_INC=$PNG_INC" echo " PNG_LIB=$PNG_LIB" ILIST="png.i $ILIST" OLIST="ypng.o spng.o $OLIST" fi #------------------------------------------------------------------------ # find jpeg header and library cat >cfg.c < #include "jpeglib.h" int main(int argc, char *argv[]) { struct jpeg_decompress_struct jpeg; jpeg_create_decompress(&jpeg); jpeg_stdio_src(&jpeg, 0); jpeg_destroy_decompress(&jpeg); return 0; } EOF # unless JPEG_INC or JPEG_LIB environment variables set, they will be blank if test -n "$jpeg_path"; then JPEG_INC=-I$jpeg_path if test $use_a = "yes" -a -r "$jpeg_path/libjpeg.a"; then JPEG_LIB="$jpeg_path/libjpeg.a" else JPEG_LIB="-L$jpeg_path -ljpeg" fi else JPEG_LIB=-ljpeg fi libs="$JPEG_LIB" found="no" if $CC $CFLAGS $JPEG_INC -o cfg cfg.c $libs >cfg.4 2>&1; then found="yes" else if test -n "$jpeg_path"; then echo "WARNING: --jpeg=$jpeg_path DID NOT WORK, IS IT BUILT?" fi for p in $plist; do JPEG_INC=-I$p/include JPEG_LIB="-L$p/lib -ljpeg" libs="$JPEG_LIB" if $CC $CFLAGS $JPEG_INC -o cfg cfg.c $libs >cfg.5 2>&1; then found="yes" break fi done fi if test $found = no; then has_jpeg=no echo "jpeg: not found" JPEG_INC= JPEG_LIB= else has_jpeg=yes echo "jpeg: found" echo " JPEG_INC=$JPEG_INC" echo " JPEG_LIB=$JPEG_LIB" ILIST="jpeg.i $ILIST" OLIST="yjpeg.o $OLIST" fi #------------------------------------------------------------------------ if test $av_dlopen != skip; then # find avcodec header and library cat >cfg.c <cfg.6 2>&1; then found="yes" else if test -n "$av_path"; then echo "WARNING: --avcodec=$av_path DID NOT WORK, IS IT BUILT?" fi for p in $plist; do AVCODEC_INC=-I$p/include AVCODEC_LIB="-L$p/lib -lavcodec" libs="$AVCODEC_LIB -lm" if $CC $CFLAGS $AVCODEC_INC -o cfg cfg.c $libs >cfg.7 2>&1; then found="yes" break fi done fi if test $av_dlopen = yes; then has_avcodec=dlopen if test $found = no; then echo "avcodec: not found, will try dlopen at runtime" else echo "avcodec: found, but will try dlopen at runtime" fi AVCODEC_INC="-DYAVC_SHARED" AVCODEC_LIB= ILIST="mpeg.i $ILIST" OLIST="ympeg.o $OLIST" elif test $found = no; then has_avcodec=no echo "avcodec: not found" AVCODEC_INC= AVCODEC_LIB= else has_avcodec=yes need_lm=yes echo "avcodec: found" echo " AVCODEC_INC=$AVCODEC_INC" echo " AVCODEC_LIB=$AVCODEC_LIB" ILIST="mpeg.i $ILIST" OLIST="ympeg.o $OLIST" fi else has_avcodec=no fi #---------------------------------------------------------------------- rm -f yorz.i cat >yorz.i <>yorz.i <>yorz.i <>yorz.i <>yorz.i <Makeyorz </dev/null 2>&1; then # or use test -s $f ? echo "WARNING - check compiler message in $f" else # remove empty files rm -f $f fi done else rm -f cfg.[0-9] fi echo "" echo "================ yorick-z configuration completed ================" exit $fatality yorick-z/jpeg.i0000644000175000017500000000441710731065646013624 0ustar thibautthibaut/* * $Id: jpeg.i,v 1.3 2007/12/16 00:04:54 dhmunro Exp $ * yorick interface to jpeg image compression * ftp://ftp.uu.net/graphics/jpeg/ http://www.faqs.org/faqs/jpeg-faq/ */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ if (!is_void(plug_in)) plug_in, "yorz"; func jpeg2(name) /* DOCUMENT jpeg2, name writes the picture in the current graphics window to the jpeg file NAME, or to NAME+".jpg" is NAME does not end in ".jpg". SEE ALSO: jpeg, png, pdf, eps, hcps */ { if (strpart(name,-3:0)!=".jpg") name+= ".jpg"; jpeg_write, name, rgb_read(); return name; } extern jpeg_read; /* DOCUMENT image = jpeg_read(filename) * or image = jpeg_read(filename, comments) * or shape = jpeg_read(filename, comments, [0,0,0,0]) * or image = jpeg_read(filename, comments, subset) * * Read jpeg file FILENAME. The returned IMAGE is 3-by-width-by-height * for rgb images (the usual case) or just width-by-height for grayscale * images. Note that the scanline order is top-to-bottom. * If COMMENTS is present, it must be a simple variable reference. * That variable will be set to either nil or a string array containing * all the descriptive comments in the file. * * In the third form, the return value is [nchan,width,height] instead * of the image, where nchan=1 or nchan=3. * In the fourth form, SUBSET is [i0,i1,j0,j1] and the returned image is * the subset full_image(..,i0:i1,j0:j1) of the full image. (This is * inefficient, but, for example, some Mars Rover pictures released by * NASA are inconveniently large.) * * SEE ALSO: jpeg_write */ extern jpeg_write; /* DOCUMENT jpeg_write, filename, image * or jpeg_write, filename, image, comments, quality * * Write jpeg file FILENAME containing IMAGE at the specified QUALITY. * The default QUALITY is 75; the range is from 0 to 100. The IMAGE * can be either 3-by-width-by-height for rgb or width-by-height for * grayscale. Note that scanline order is top-to-bottom. * If COMMENTS is non-nil, it is a string or an array of strings that * will be written as descriptive comments in the jpeg file. * * SEE ALSO: jpeg_read */ yorick-z/yjpeg.c0000644000175000017500000001543010313362415013772 0ustar thibautthibaut/* * $Id: yjpeg.c,v 1.1.1.1 2005/09/18 22:07:09 dhmunro Exp $ * jpeg interface for yorick */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #include "ydata.h" #include "yio.h" #include "pstdlib.h" #include #include #include "jpeglib.h" #define YJ_DEFAULT_QUALITY 75 extern BuiltIn Y_jpeg_read, Y_jpeg_write; typedef struct yj_error_mgr yj_error_mgr; struct yj_error_mgr { struct jpeg_error_mgr base; FILE *file; }; static void yj_output_message(j_common_ptr jpeg); static void yj_error_exit(j_common_ptr jpeg); void Y_jpeg_read(int nArgs) { long icom = (nArgs>=2)? YGet_Ref(sp-nArgs+2) : -1; Dimension *dims = 0; long *lims = (nArgs>=3)? YGet_L(sp-nArgs+3, 1, &dims) : 0; char *filename = (nArgs>=1)? p_native(YGetString(sp-nArgs+1)) : 0; FILE *file = (filename && filename[0])? fopen(filename, "rb") : 0; struct jpeg_decompress_struct jpeg; struct yj_error_mgr jerr; JSAMPROW image, *row_pointer; int i, j, row_stride; p_free(filename); if (nArgs<1 || nArgs>3) YError("jpeg_read takes 1, 2, or 3 arguments"); if (lims && TotalNumber(dims)!=4) YError("jpeg_read third argument must be [xmin,xmax,ymin,ymax]"); if (!file) YError("jpeg_read cannot open specified file"); jpeg.err = jpeg_std_error(&jerr.base); jerr.base.error_exit = yj_error_exit; jerr.base.output_message = yj_output_message; jerr.file = file; jpeg_create_decompress(&jpeg); jpeg_stdio_src(&jpeg, file); if (icom >= 0) jpeg_save_markers(&jpeg, JPEG_COM, 0xffff); jpeg_read_header(&jpeg, TRUE); if (icom >= 0) { jpeg_saved_marker_ptr mk = jpeg.marker_list; long ncom = 0; for (mk=jpeg.marker_list ; mk ; mk=mk->next) if (mk->marker==JPEG_COM && mk->data_length>0) ncom++; if (ncom) { Array *a = (Array *)PushDataBlock(NewArray(&stringStruct, ynew_dim(ncom, 0))); char **com = a->value.q; long i = 0; for (mk=jpeg.marker_list ; mk ; mk=mk->next) { if (mk->marker==JPEG_COM && mk->data_length>0) com[i++] = p_strncat(0, (char *)mk->data, mk->data_length & 0xffff); } } else { PushDataBlock(RefNC(&nilDB)); } YPut_Result(sp, icom); /* was sp-nArgs+2 before push */ Drop(1); } jpeg_calc_output_dimensions(&jpeg); if (lims && (lims[0]<1 || lims[2]<1 || lims[0]>lims[1] || lims[2]>lims[3] || lims[1]>jpeg.output_width || lims[3]>jpeg.output_height)) { /* just return dimensions */ Dimension *d = ynew_dim(3L, 0); Array *a = (Array *)PushDataBlock(NewArray(&longStruct, d)); a->value.l[0] = jpeg.output_components; a->value.l[1] = jpeg.output_width; a->value.l[2] = jpeg.output_height; } else { int nchan = jpeg.output_components; Dimension *d; Array *a; long x0 = lims? lims[0] : 1; long x1 = lims? lims[1] : jpeg.output_width; long y0 = lims? lims[2] : 1; long y1 = lims? lims[3] : jpeg.output_height; row_stride = jpeg.output_width * jpeg.output_components; row_pointer = jpeg.mem->alloc_sarray((j_common_ptr)&jpeg, JPOOL_IMAGE, row_stride, 1); jpeg_start_decompress(&jpeg); d = ynew_dim(y1-y0+1, NewDimension(x1-x0+1, 1L, (nchan==1)? 0 : NewDimension((long)nchan, 1L, 0))); #if BITS_IN_JSAMPLE == 8 a = (Array *)PushDataBlock(NewArray(&charStruct, d)); image = (JSAMPLE *)a->value.c; #elif BITS_IN_JSAMPLE == 12 a = (Array *)PushDataBlock(NewArray(&shortStruct, d)); image = (JSAMPLE *)a->value.s; #else #error unsupported BITS_IN_JSAMPLE #endif x0 = (x0-1)*jpeg.output_components; x1 *= jpeg.output_components; for (i=0 ; jpeg.output_scanline=3)? YGet_Q(sp-nArgs+3, 1, &dims) : 0; long ncom = com? TotalNumber(dims) : 0; int quality = (nArgs==4)? YGetInteger(sp-nArgs+4) : -1; #if BITS_IN_JSAMPLE == 8 JSAMPROW image = (JSAMPROW)((nArgs>=2)? YGet_C(sp-nArgs+2, 0, &dims) : 0); #elif BITS_IN_JSAMPLE == 12 JSAMPROW image = (JSAMPROW)((nArgs>=2)? YGet_S(sp-nArgs+2, 0, &dims) : 0); #else #error unsupported BITS_IN_JSAMPLE #endif int ndims = YGet_dims(dims, idims, 3); JSAMPROW row_pointer[1]; char *filename = (nArgs>=2)? p_native(YGetString(sp-nArgs+1)) : 0; FILE *file = (filename && filename[0])? fopen(filename, "wb") : 0; struct jpeg_compress_struct jpeg; struct yj_error_mgr jerr; int i, row_stride; p_free(filename); if (nArgs<2 || nArgs>4) YError("jpeg_write takes 2, 3, or 4 arguments"); if (!file) YError("jpeg_write cannot open specified file"); if (ndims==2) idims[2]=idims[1], idims[1]=idims[0], idims[0]=1; if (ndims<2 || ndims>3 || (idims[0]!=1 && idims[0]!=3)) YError("jpeg_write needs 2D gray or rgb image"); jpeg.err = jpeg_std_error(&jerr.base); jerr.base.error_exit = yj_error_exit; jerr.base.output_message = yj_output_message; jerr.file = file; jpeg_create_compress(&jpeg); jpeg_stdio_dest(&jpeg, file); jpeg.image_width = idims[1]; jpeg.image_height = idims[2]; jpeg.input_components = idims[0]; jpeg.in_color_space = (idims[0]==3)? JCS_RGB : JCS_GRAYSCALE; jpeg_set_defaults(&jpeg); if (quality <= 0) quality = YJ_DEFAULT_QUALITY; else if (quality > 100) quality = 100; jpeg_set_quality(&jpeg, quality, TRUE); jpeg_start_compress(&jpeg, TRUE); for (i=0 ; iis_decompressor) { strcpy(msg, "jpeg_read: "); jpeg->err->format_message(jpeg, msg+11); jpeg_destroy_decompress((j_decompress_ptr)jpeg); } else { strcpy(msg, "jpeg_write: "); jpeg->err->format_message(jpeg, msg+12); jpeg_destroy_compress((j_compress_ptr)jpeg); } if (yjpeg->file) fclose(yjpeg->file); yjpeg->file = 0; YError(msg); } static void yj_output_message(j_common_ptr jpeg) { /* silently ignore warning messages -- it's not our job to track * down irregularities in jpeg files */ } yorick-z/check.i0000644000175000017500000000233210313362417013736 0ustar thibautthibaut/* $Id: check.i,v 1.1.1.1 2005/09/18 22:07:11 dhmunro Exp $ */ plug_dir, ["."]; write, "\n\n---------------------------------------checking zlib.i"; require, "ztest.i"; if (typeof(z_deflate) == "builtin") ztest; else write, "************** no zlib support in this yorick-z"; write, "\n\n---------------------------------------checking png.i"; require, "pngtest.i"; if (typeof(_png_read) == "builtin") pngtest; else write, "************** no png support in this yorick-z"; write, "\n\n---------------------------------------checking jpeg.i"; require, "jpgtest.i"; if (typeof(jpeg_read) == "builtin") jpgtest; else write, "************** no jpeg support in this yorick-z"; write, "\n\n---------------------------------------checking mpeg.i"; require, "mpgtest.i"; func do_mpgtest { if (typeof(mpeg_create) != "builtin") { write, "************** no mpeg support in this yorick-z"; return; } if (catch(-1)) { write, "caught interpreted error while checking mpeg.i"; write, "... libavcodec (ffmpeg) may not be installed"; return; } mpgtest; write, "************** created test.mpg, check it using mpeg viewer"; } do_mpgtest; write, "\n\n---------------------------------------yorick-z tests complete"; quit; yorick-z/pngtest.i0000644000175000017500000001624610313362416014355 0ustar thibautthibaut/* * $Id: pngtest.i,v 1.1.1.1 2005/09/18 22:07:10 dhmunro Exp $ * test yorick png interface */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ require, "png.i"; func pngtest(keep=) { pal = get_palette("earth.gp"); npal = numberof(pal)/3; depth = 0; nfo = []; x = span(-3,4,400)(,-:1:380); y = span(-4,3,380)(-:1:400,); z = (16.-abs(x,y)^2)*sin(1.5*x-y+.5*x*y); zb = bytscl(z, top=npal-1); png_write, "test-gray.png", zb; png_write, "test-pal.png", zb, palette=pal; png_write, "test-rgb.png", pal(,1+zb); im = png_read("test-gray.png"); if (x1 = anyof(im!=zb)) write, "FAILURE: test-gray.png (image)"; else write, "OK: test-gray.png"; if (!x1 && !keep) remove, "test-gray.png"; im = png_read("test-pal.png", depth, nfo); if (x1 = anyof(im!=zb)) write, "FAILURE: test-pal.png (image)"; if (x2 = anyof(pal!=*nfo(1))) write, "FAILURE: test-pal.png (palette)"; if (!x1 && !x2) write, "OK: test-pal.png"; if (!x1 && !x2 && !keep) remove, "test-pal.png"; im = png_read("test-rgb.png"); if (x1 = anyof(im!=pal(,1+zb))) write, "FAILURE: test-rgb.png (image)"; else write, "OK: test-rgb.png"; if (!x1 && !keep) remove, "test-rgb.png"; superlong = "Super long string (above 1024 characters) will become zTXt.\n"; superlong += superlong; /* 120 chars */ superlong += superlong; /* 240 chars */ superlong += superlong; /* 480 chars */ superlong += superlong; /* 960 chars */ superlong += superlong; /* 1920 chars */ ts = timestamp(); kt = [["Title", "funky scythes"], ["Description", "test of yorick png interface"], ["Creation Time", ts], ["Comment", "This is a very long comment containing embedded\n"+ "newline characters. However, it does not begin\n"+ "to approach the 1024 character zTXt cutoff."], ["Test-ztxt", superlong]]; tr1 = '\60'; tr3 = pal(,49); alpha = array('\377', npal); alpha(1:49) = 0; bk1 = 100; bk3 = [255,0,0]; pcal = [0, 1023, 255, 3, 0., 1.3, 2.5, 512.]; pcals = ["test calibration", "bogomips"]; scal = [400., 380., 1]; phys = [5000, 5000, 1]; time = [2004, 1, 20, 20, 0, 0]; png_write, "test-all.png", zb, palette=pal, alpha=alpha, bkgd=bk1, pcal=pcal, pcals=pcals, scal=scal, phys=phys, time=time, text=kt; im = png_read("test-all.png", depth, nfo); x = [anyof(im!=zb), anyof(pal!=*nfo(1)), anyof(alpha!=*nfo(2)), anyof(bk1!=*nfo(3)), anyof(pcal!=*nfo(4)), anyof(pcals!=*nfo(5)), anyof(scal!=*nfo(6)), anyof(phys!=*nfo(7)), anyof(kt!=*nfo(8)), anyof(time!=*nfo(9))]; if (noneof(x)) write, "OK: test-all.png"; else { write, "FAILURE: test-all.png:"; x; } if (noneof(x) && !keep) remove, "test-all.png"; zb3 = pal(,1+max(zb,48)); png_write, "test-rgbx.png", zb3, trns=tr3, bkgd=bk3, pcal=pcal, pcals=pcals, scal=scal, phys=phys, time=time, text=kt; im = png_read("test-rgbx.png", depth, nfo); x = [anyof(im!=zb3), !is_void(*nfo(1)), anyof(tr3!=*nfo(2)), anyof(bk3!=*nfo(3)), anyof(pcal!=*nfo(4)), anyof(pcals!=*nfo(5)), anyof(scal!=*nfo(6)), anyof(phys!=*nfo(7)), anyof(kt!=*nfo(8)), anyof(time!=*nfo(9))]; if (noneof(x)) write, "OK: test-rgbx.png"; else { write, "FAILURE: test-rgbx.png:"; x; } if (noneof(x) && !keep) remove, "test-rgbx.png"; zb = short(long(65535.999*(z-min(z))/(max(z)-min(z)))); png_write, "test-gray16.png", zb; im = png_read("test-gray16.png"); if (x1 = (anyof(im!=zb) || structof(im)!=short)) write, "FAILURE: test-gray16.png (image)"; else write, "OK: test-gray16.png"; if (!x1 && !keep) remove, "test-gray16.png"; zb = short(1023.999*(z-min(z))/(max(z)-min(z))); png_write, "test-gray10.png", zb, 10; im = png_read("test-gray10.png"); if (x1 = (anyof(im!=zb) || structof(im)!=short)) write, "FAILURE: test-gray10.png (image)"; else write, "OK: test-gray10.png"; if (!x1 && !keep) remove, "test-gray10.png"; } func get_palette(name) { if (strmatch(name,"/") || strmatch(name,"\\")) f = open(name); else f = open(Y_SITE+"g/"+name); lines = rdline(f, 2000); lines = lines(where(lines)); tok = strtok(lines, " \t=")(1,); list = where((tok>="0") & (tok<="999999")); lines = lines(list); npal = numberof(lines); palette = array(char, 3, npal); if (sread(lines, palette) != 3*npal) error, "problem reading palette "+name; return palette; } /* ------------ independent png file partial decoder ------------- */ func pngdec(name, &plte) { f = open(name, "rb"); xdr_primitives, f; sig = array(char, 8); if (_read(f,0,sig)!=8 || anyof(sig!=[137,80,78,71,13,10,26,10])) { write, "bad PNG signature -- "+name+" not a PNG"; return; } addr = 8; type = crc = []; data = pngchunk(f, addr, type, crc); if (structof(type)!=string) return; if (type != "IHDR" || numberof(data)!=13) { write, "expecting IHDR chunk, got "+type; return; } ldat = long(data(1:8)); width = (ldat(1)<<24) | (ldat(2)<<16) | (ldat(3)<<8) | ldat(4); height = (ldat(5)<<24) | (ldat(6)<<16) | (ldat(7)<<8) | ldat(8); depth = long(data(9)); ctype = long(data(10)); cmpr = long(data(11)); filt = long(data(12)); intl = long(data(13)); if (ctype == 0) ctype = "gray"; else if (ctype == 2) ctype = "y+a"; else if (ctype == 3) ctype = "plte"; else if (ctype == 4) ctype = "rgb"; else if (ctype == 6) ctype = "rgba"; else ctype = "???" write, width, height, depth, ctype, cmpr, filt, intl, format="shape= %ldx%ld depth= %ld ctype= %s c f i = %ld %ld %ld\n"; write, format="crc = 0x%08lx check = 0x%08lx\n", crc, pngcrc(type,data); for (;;) { write, format="%ld ", addr; data = pngchunk(f, addr, type, crc); if (structof(type)!=string || type=="IEND") break; write, format="%s crc = 0x%08lx check = 0x%08lx\n", type, crc, pngcrc(type,data); write, type; if (type=="IDAT") continue; if (type=="PLTE") { npal = numberof(data)/3; plte = array(char, 3, npal); plte(*) = data; } } if (structof(type)!=string) { write, "error reading file before IEND"; return; } write, type; } func pngchunk(f, &addr, &type, &crc) { len = crc = 0; type = data = []; if (_read(f, addr, len)!=1) goto oops; addr += 4; type = array(char, 4); if (_read(f, addr, type)!=4) goto oops; addr += 4; type = string(&type); if (len > 0) { data = array(char, len); if (_read(f, addr, data)!=len) goto oops; addr += len; } if (_read(f, addr, crc)!=1) goto oops; addr += 4; return data; oops: write, "bad PNG chunk"; type = []; return []; } pngtable = []; func pngcrc(type, data) { if (is_void(pngtable)) { pngtable = array(long, 256); for (n=0 ; n<256 ; n++) { c = n; for (k=0 ; k<8 ; k++) { if (c & 1) c = 0xedb88320 ~ ((c >> 1) & 0x7fffffff); else c = (c >> 1) & 0x7fffffff; } pngtable(n+1) = c; } } type = (*pointer(type))(1:4); grow, type, data; c = 0xffffffff; for (n=1 ; n<=numberof(type) ; n++) { c = pngtable(1+((c ~ type(n)) & 0xff)) ~ ((c >> 8) & 0xffffff); } c = c ~ 0xffffffff; return c; } yorick-z/mpeg.i0000644000175000017500000000724510313362414013616 0ustar thibautthibaut/* * $Id: mpeg.i,v 1.1.1.1 2005/09/18 22:07:08 dhmunro Exp $ * yorick interface to mpeg movie encoding * */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ if (!is_void(plug_in)) plug_in, "yorz"; extern mpeg_create; /* DOCUMENT mpeg = mpeg_create(filename) * or mpeg = mpeg_create(filename, params) * * Create an mpeg-1 movie file FILENAME. Write frames with mpeg_write, * close with mpeg_close. The return value is an mpeg encoder object. * * If given, PARAMS is [bit_rate, frame_rate, gop_size, max_b_frames] * which default to [ 400000, 25, 10, 1 ] * The rates are per second, the gop_size is the number of frames * before an I-frame is emitted, and max_b_frames is the largest * number of consecutive B-frames. (The third kind of frame is the * P-frame; generally, the encoder emits B-frames until it is forced * to emit a P-frame by max_b_frames, or an I-frame by gop_size. The * smaller these numbers, the higher quality the movie, but the lower * the compression.) Any of the four PARAMS values may be zero to * get the default value, except for max_b_frames, which should be <0 * to get the default value. * * SEE ALSO: mpeg_write, mpeg_close, mpeg_movie */ extern mpeg_write; /* DOCUMENT mpeg_write, mpeg, rgb * * Write a frame RGB into the mpeg file corresponding to the MPEG * encoder returned by mpeg_create. RGB is a 3-by-width-by-height * array of char. Every frame must have the same width and height. * To finish the movie and close the file, call mpeg_close. * * Note that you may have trouble rendering the resulting mpeg * file if the image width and height are note multiples of 8. * * SEE ALSO: mpeg_create, mpeg_close, mpeg_movie */ func mpeg_close(&mpeg) /* DOCUMENT mpeg_close, mpeg * * Close the mpeg file corresponding to the MPEG encoder. Actually, * this merely destroys the reference to the encoder; the file will * remain open until the final reference is destroyed. * * SEE ALSO: mpeg_create, mpeg_write, mpeg_movie */ { mpeg = []; } func mpeg_movie(filename, draw_frame,time_limit,min_interframe,bracket_time) /* DOCUMENT mpeg_movie, filename, draw_frame * or mpeg_movie, filename, draw_frame, time_limit * or mpeg_movie, filename, draw_frame, time_limit, min_interframe * * An extension of the movie function (#include "movie.i") that generates * an mpeg file FILENAME. The other arguments are the same as the movie * function (which see). The draw_frame function is: * * func draw_frame(i) * { * // Input argument i is the frame number. * // draw_frame should return non-zero if there are more * // frames in this movie. A zero return will stop the * // movie. * // draw_frame must NOT include any fma command if the * // making_movie variable is set (movie sets this variable * // before calling draw_frame) * } * * SEE ALSO: movie, mpeg_create, mpeg_write, mpeg_close */ { require, "movie.i"; _mpeg_movie_mpeg = mpeg_create(filename, [0, 0, 16, 2]); fma = _mpeg_movie_fma; _mpeg_movie_count = 0; return movie(draw_frame, time_limit, min_interframe, bracket_time); } if (is_void(_mpeg_movie_fma0)) _mpeg_movie_fma0 = fma; func _mpeg_movie_fma { /* movie function does one fma before first draw_frame, skip it */ if (_mpeg_movie_count++) { rgb = rgb_read(); /* trim image until divisible by 8 */ n = dimsof(rgb)(3:4) & 7; if (anyof(n)) rgb = rgb(,n(1)/2+1:-(n(1)+1)/2,n(2)/2+1:-(n(2)+1)/2); mpeg_write, _mpeg_movie_mpeg, rgb; } _mpeg_movie_fma0; } yorick-z/yavcodec.h0000644000175000017500000000560210313362417014460 0ustar thibautthibaut/* * $Id: yavcodec.h,v 1.1.1.1 2005/09/18 22:07:11 dhmunro Exp $ * subset of avcodec.h actually used by ympeg.c */ #ifndef AVCODEC_H #define AVCODEC_H #ifdef __cplusplus extern "C" { #endif #define LIBAVCODEC_VERSION_INT 0x000409 enum PixelFormat { PIX_FMT_YUV420P, PIX_FMT_YUV422, PIX_FMT_RGB24 /* many more unused by ympeg.c */ }; enum CodecID { CODEC_ID_NONE, CODEC_ID_MPEG1VIDEO /* many more unused by ympeg.c */ }; /* typedef unsigned char uint8_t; */ /* some systems define uint8_t, others do not, workaround is macro */ #ifndef uint8_t # define uint8_t unsigned char #endif typedef struct AVFrame AVFrame; typedef struct AVPicture AVPicture; typedef struct AVCodecContext AVCodecContext; typedef struct AVCodec AVCodec; extern AVCodec mpeg1video_encoder; extern unsigned int avcodec_version(void); extern void avcodec_init(void); extern void register_avcodec(AVCodec *format); extern AVCodec *avcodec_find_encoder(enum CodecID id); extern AVCodecContext *avcodec_alloc_context(void); extern AVFrame *avcodec_alloc_frame(void); extern int avcodec_open(AVCodecContext *avctx, AVCodec *codec); extern int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVFrame *pict); extern int avcodec_close(AVCodecContext *avctx); extern void *av_malloc(unsigned int size); extern void av_free(void *ptr); extern int avpicture_get_size(int pix_fmt, int width, int height); extern int avpicture_fill(AVPicture *picture, uint8_t *ptr, int pix_fmt, int width, int height); extern int img_convert(AVPicture *dst, int dst_pix_fmt, AVPicture *src, int pix_fmt, int width, int height); struct AVPicture { /* members opaque, but size required */ uint8_t *data[4]; int linesize[4]; }; typedef struct AVClass AVClass; struct AVCodecContext { /* several members must be set */ AVClass *av_class; /* not present in ffmpeg-0.4.8 */ int bit_rate; /* used */ int bit_rate_tolerance; int flags; int sub_id; int me_method; void *extradata; int extradata_size; int frame_rate; /* used */ int width, height; /* used */ int gop_size; /* used */ enum PixelFormat pix_fmt; int rate_emu; void (*draw_horiz_band)(void); int sample_rate; int channels; int sample_fmt; int frame_size; int frame_number; int real_pict_num; int delay; float qcompress; float qblur; int qmin; int qmax; int max_qdiff; int max_b_frames; /* used */ /* ... many more unused by ympeg.c * in particular frame_rate_base is way down in member list * but default value of 1 just means frame_rate is in frames/sec * mpeg12.c code apparently adjusts these to look like * frame_rate_base=1001 no matter what its actual value */ }; #ifdef __cplusplus } #endif #endif /* AVCODEC_H */ yorick-z/zlib.i0000644000175000017500000001414510313362414013623 0ustar thibautthibaut/* * $Id: zlib.i,v 1.1.1.1 2005/09/18 22:07:08 dhmunro Exp $ * yorick interface to zlib data compression library */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ if (!is_void(plug_in)) plug_in, "yorz"; /* NOTE: * the gz stream functions are not wrapped -- for text files, you can * get that functionality with the popen function and gzip program */ extern z_deflate; /* DOCUMENT buffer = z_deflate() * or buffer = z_deflate(level) * or buffer = z_deflate(level, dictionary) * then navail = z_deflate(buffer, data) * or zdata = z_flush(buffer) * finally zdata = z_flush(buffer, data) * or zdata = z_flush(buffer, -) * * In any of the first three forms, initiate a zlib deflation * BUFFER. The second two forms allow you to specify a compression * LEVEL (0-9 in increasing compression and decreasing speed), and/or * a special compression DICTIONARY (which you will need to supply * again in order to decompress the data later). * * After the BUFFER has been created, use z_deflate to compress DATA, * adding it to the compressed stream in the BUFFER. After one or * several calls to z_deflate, you can call z_flush in the first form * to extract the current BUFFER contents as ZDATA, the portion of * the compressed data stream stored in BUFFER. You can alternate * calls to z_deflate and z_flush as many times as you like in order * to compress an arbitrary amount of DATA into ZDATA without filling * memory. The NAVAIL returned by z_deflate is a lower limit on the * number of bytes of compressed data a subsequent z_flush will return. * * The final block of DATA must be compressed by a call to z_flush, * in the final form. This flushes all remaining data into the * resulting ZDATA and closes the BUFFER. You can call z_flush * in this form immediately after creating the buffer, so that * the tersest way to compress a single block of data is: * zdata = z_flush(z_deflate(), data) * Use - for DATA to indicate you have no more DATA, but want to * finish the compression. * * SEE ALSO: z_inflate, z_flush, z_crc32 */ extern z_inflate; /* DOCUMENT buffer = z_inflate() * then flag = z_inflate(buffer, zdata) * or flag = z_inflate(buffer, zdata, data) * or data = z_flush(buffer) * or data = z_flush(buffer, type) * * In the first form, initiate a zlib inflation BUFFER. You use * that BUFFER in subsequent calls to z_inflate if you do not know * in advance how large the uncompressed DATA will be, or if you * want to do the decompression in chunks to conserve memory. * * Use the second or third forms to actually decompress ZDATA. * After one or more calls to z_inflate, you can call z_flush in * order to extract whatever uncompressed DATA has so far been * produced. You can optionally specify a TYPE array for * z_flush, otherwise the DATA will be a 1D array of char. * * Alternatively, you can supply a DATA array as the third parameter * to z_inflate, in which case z_inflate will uncompress to your DATA * array instead of to an internal array in BUFFER. You can use this * form if you already know the size and data type the data will * decompress to. If the returned flag is 3, you can call z_setdict * and repeat the call. Otherwise, a return value other than 0 * probably represents an error. Note that z_flush will not return * bytes that have been written to a DATA array supplied to z_inflate. * * The FLAG returned by z_inflate is * 0 if the ZDATA stream is complete, in which case no * further calls to z_inflate are legal with that BUFFER * - the next call to z_flush will return all remaining * bytes of the uncompressed data * 1 if the ZDATA stream is incomplete, but no additional * uncompressed data is yet available in BUFFER * 2 if the ZDATA stream is incomplete, and uncompressed data * can be retrieved from BUFFER by calling z_flush * 3 if a DICTIONARY is required to continue decompression * - use z_setdict to set a dictionary and call z_inflate * a second time with the same DATA * -1 if the ZDATA stream completed, but contained additional * bytes after the end * -2 if the ZDATA stream is corrupted * * SEE ALSO: z_deflate, z_flush, z_setdict, z_crc32 */ extern z_flush; /* DOCUMENT zdata_or_data = z_flush(buffer) * or zdata = z_flush(buffer, data) * or zdata = z_flush(buffer, -) * or data = z_flush(buffer, type) * * Flushes all available ZDATA (if STATE is a z_deflate state) or * all available DATA (if STATE is a z_inflate state). For z_deflate * states, a second argument to z_flush is the final DATA block to * complete the ZDATA stream. For z_inflate states, you may specify * an array data TYPE so that the return DATA value will have that * data type instead of char. * * SEE ALSO: z_deflate, z_inflate, z_setdict */ extern z_setdict; /* DOCUMENT adler32 = z_setdict(buffer) * or flag = z_setdict(buffer, dictionary) * * In the first form, returns the adler32 checksum of the dictionary * required to continue decompressing a stream after z_inflate * returns 3, or [] (nil) if BUFFER does not need a dictionary. * You can also use this form to retrieve the adler32 checksum of * a dictionary you supplied in the call to z_deflate that * returned BUFFER. * * In the second form, sets the DICTIONARY for BUFFER so that * succeeding calls to z_inflate can continue decompressing. The * return value FLAG is 1 on success, or 0 on failure. * * You can compute the adler32 checksum using the z_crc32 function. * * SEE ALSO: z_inflate, z_crc32 */ extern z_crc32; /* DOCUMENT crc32 = z_crc32(crc32, data) * or adler32 = z_crc32(adler32, data, 1) * * Compute the crc32 or adler32 checksum of DATA. The first * argument can be [] (nil) if this is the first chunk of DATA; * to checksum a long stream of data you can call z_crc32 on * a series of chunks, feeding the result of each call as input * to the following call. * * SEE ALSO: z_setdict */ yorick-z/README0000644000175000017500000001506710313362414013375 0ustar thibautthibaut-------- YORICK-Z -------- This is a compiled add-on for yorick (an interpreted computer language specialized for numerical and scientific problems). Yorick-z adds support for zlib (the data compression system used by gzip), png (a lossless image compression format), jpeg (a lossy image compression format), and mpeg (mpeg1, a compressed video format). These are not supported in the basic yorick distribution, because each relies on a specialized library beyond what is required for basic yorick functionality. (On Unix systems, yorick requires only libc, libm, and libX11. On Windows systems, yorick requires only dlls which ship with every Windows system.) The specific dependencies for yorick-z are: libz http://www.zlib.org or http://www.gzip.org/zlib/ - compression scheme used by gzip (.gz files) libpng http://www.libpng.org/pub/png/ also ftp://ftp.uu.net/graphics/png - .png image files, depends on libz libjpeg http://www.ijg.org/ also ftp://ftp.uu.net/graphics/jpeg/ - .jpg image files libavcodec http://ffmpeg.sourceforge.net/ - .mpg video files The APIs for these packages are not completely stable. The yorick-z package will work with the following versions: zlib >= 1.1.4 libpng >= 1.2.8 (>=1.2.2 on little endian machines, eg pentium) libjpeg >= 6b ffmpeg = 0.4.8 or 0.4.9-pre1 (particularly unstable API) The yorick-z package supports zlib compression and decompression, both reading and writing of png and jpeg images, and only writing of mpeg1 video movies. You can configure yorick-z to build any one or all of these packages, so you do not need to have, for example, libz, libpng, or libavcodec to build a version of yorick with jpeg support. Ordinarily, any of these libraries would be present on a system as a shared library, which will be dynamically linked to yorick at runtime. However, you are free to link any of them statically. The libz, libpng, and libjpeg shared libraries are tolerably widespread, since most web browsers use those libraries. However, at this writing, libavcodec (ffmpeg) is relatively rare, that is, you will likely need to make a special effort to acquire and install it on your system if you want the yorick-z mpeg1 support. In recognition of this fact, yorick-z allows you a third option for libavcodec, in addition to either a static link, or a build-time link to a shared library: Namely, you can configure yorick-z to dlopen libavcodec at the first reference to any of the mpeg1 functionality. That is, you can build yorick-z in such a way that the mpeg1 functionality becomes available when you install libavcodec, but the other parts of yorick-z all work properly if you don't have libavcodec. (Note: This does not work under MacOS X.) ----------------- BUILDING YORICK-Z ----------------- To build yorick-z, unpack it, cd into the top-level directory, and type: ./configure make To test the package, type: make check To install the package, type (as root): make install Before you do any of this, you need a working yorick that is on your PATH (e.i.- so that when you type "yorick" at a command shell prompt, the code starts). You also need to have installed zlib (the libz library), libpng, and libjpeg. If libavcodec (part of ffmpeg) is not installed, then yorick-z mpeg support will not work until it is installed. The absence of either the headers or libraries for the other packages will result in them being omitted entirely during the build. See the LIBAVCODEC (mpeg1) section below for detailed description of the configuration options for that library. If the libraries or headers are not installed in a standard place ($prefix/include for headers and $prefix/lib for libraries, where $prefix is /usr, /usr/local, or /sw), then you can use the --zlib, --png, --jpeg, or --avcodec options to ./configure to point the script to the directories where you built those libraries: Usage: ./configure [options] Options are one or more of: --yorick=/path/to/yorick set path to yorick executable (if not on your PATH) --zlib=/path/to/zlib-version set path to directory containing zlib.h and libz.a --png=/path/to/png-version set path to directory containing png.h and libpng.a --jpeg=/path/to/jpeg-version set path to directory containing jpeglib.h and libjpeg.a --avcodec=/path/to/ffmpeg-version/libavcodec set path to directory containing avcodec.h and libavcodec.a --dl-avcodec use dlopen to link to libavcodec at runtime --no-avcodec skip libavcodec (mpeg1) support entirely --a generate /path/to/pkg/libpkg.a on load line instead of the default -L/path/to/pkg -lpkg This is the only way to force a particular static library to be loaded on some platforms (e.g.- MacOS X). Note that the --zlib, --png, --jpeg, and --avcodec options presume that you have built, but NOT installed those packages. That is, the paths are the names of the directories in your source tree. Of course, if you install them in a standard place like /usr/lib or /usr/local/lib, you don't need these options at all. If you need even finer control than this (for example, to separately specify directory paths for header and library files), you can set environment variables before running configure (read the configure script for details), or edit Makeyorz by hand after running configure. --------------------------------- LIBAVCODEC (mpeg1) dlopen support --------------------------------- The configure script will assume you want dlopen support for libavcodec, which does not require any headers at build time, will work at runtime if libavcodec.so is installed, and fail gracefully only when you attempt to actually create an mpeg movie, if libavcodec.so has not been installed. If you later install the libavcodec shared library in a non-standard place (not /usr/lib, /usr/local/lib, nor /sw/lib), you may place the library in Y_HOME/lib (type Y_HOME in yorick to discover that directory path). If you are unable to do that, as a last resort, you may place the path name of the libavcodec shared library, minus its file extension (.so, .sl, or .dylib) in the Y_LIBAVCODEC environment variable. You can also force the configure script to try to link libavcodec at build time, as it does for libz, libpng, and libjpeg. To do this, use any one of the following configure options: --avcodec=/path/to/ffmpeg-version/libavcodec link to specified libavcodec at build time --dl-avcodec link to installed libavcodec at runtime --no-avcodec omit libavcodec (mpeg1) support, even if libavcodec present yorick-z/spng.h0000644000175000017500000001574010313362416013635 0ustar thibautthibaut/* * $Id: spng.h,v 1.1.1.1 2005/09/18 22:07:10 dhmunro Exp $ * simplified png interface, directed to scientific data storage */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #ifndef SPNG_H #define SPNG_H 1 typedef struct sp_memops sp_memops; typedef struct sp_info sp_info; struct sp_info { int depth, nchan, width, height; /* depth = 1<=depth<=16 is number of bits per channel per pixel * nchan = 1 for gray or pseudocolor * 2 for gray + alpha * 3 for RGB * 4 for RGBA * npal>0 and palette!=0 distinguishes gray from pseudocolor * depth<=8 for pseudocolor (npal<=256) * alpha is opacity, so 0 means transparent * image order is RGBA, if all channels are present * palette also legal for nchan == 3, 4 as suggested palette * */ unsigned char *cimage; /* use this if depth<=8, 1 byte per pixel */ unsigned short *simage; /* use this if depth==16 */ int npal; /* palette[npal][3], alpha[npal] */ unsigned char *palette, *alpha; /* PLTE, tRNS */ int colors; /* 0 or SP_TRNS, SP_BKGD bits */ unsigned short trns[3], bkgd[3]; /* tRNS, bKGD */ int ntxt; /* tEXt, zTXt */ char **keytxt; /* keytxt[ntxt][2] is [key,text] */ short itime[6]; /* tIME, yy/mm/dd hh:mm:ss */ /* pHYs is size as printed or scanned (n_xpix, n_ypix), (0,0) means none * pixels/meter if per_meter!=0, else just aspect ratio */ int n_xpix, n_ypix, per_meter; /* pHYs size as printed or scanned */ /* sCAL is size for depicted object * sunit == 0 for unknown, or SP_METERS or SP_RADIANS * (xpix_sz, ypix_sz) == (0,0) for no sCAL */ int sunit; /* 0 or SP_METERS or SP_RADIANS */ double xpix_sz, ypix_sz; /* pCAL is pixel value mapping */ char *purpose, *punit; int eqtype, x0, x1, mx; double p[4]; int nerrs, nwarn; /* error, warning counts */ char msg[96]; /* error or first warning message */ }; /* colors values */ #define SP_TRNS 1 #define SP_BKGD 2 /* sunit values */ #define SP_UNKNOWN 0 #define SP_METERS 1 #define SP_RADIANS 2 /* eqtype values */ #define SP_LINEAR 0 #define SP_EXP 1 #define SP_POW 2 #define SP_SINH 3 struct sp_memops { /* for simage or cimage */ void *(*imalloc)(int depth, int nchan, int width, int height); void (*ifree)(void *image); /* for palette, alpha */ void *(*cmalloc)(int nchan, int npal); void (*cfree)(void *palette); /* for keytxt array of text pointers */ void *(*pmalloc)(int ntxt); void (*pfree)(void *keytxt); /* for text strings keytxt[i], purpose, punit */ void *(*tmalloc)(int nbytes); void (*tfree)(void *text); /* for internal scratch space */ void *(*smalloc)(unsigned long nbytes); void (*sfree)(void *scratch); }; #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif extern int sp_read(const char *filename, sp_memops *memops, sp_info *info); extern int sp_write(const char *filename, sp_memops *memops, sp_info *info); extern void sp_free(sp_info *info, sp_memops *memops); extern sp_info *sp_init(sp_info *info); #if defined(__cplusplus) || defined(c_plusplus) } #endif #endif /* Not all depths are available for all values of nchan: nchan palette depths gray 1 no 1, 2, 4, 8, 16 pseudocolor 1 yes 1, 2, 4, 8 gray+alpha 2 - 8, 16 rgb 3 - 8, 16 rgba 4 - 8, 16 Note that if you do call sp_setpal, then the image depth is limited to 8 bits, so the maximum permissible value of npal is 256; png pseudocolor palettes are limited to 256 colors. This restriction to 8 bit depth means that many or even most scientific data sets should be stored as grayscale (or rgb) images. The png format also permits a palette for rgb or rgba images. In that case, the palette is merely a suggested set of colors if the rendering program is restricted to a pseudocolor display. Transparency is not allowed for this use of a palette, so alpha!=0 is an error if nchan!=1. (The spng interface always writes a PLTE chunk; spng does not support the sPLT chunk for defining more elaborate suggested palettes.) If there is no alpha channel, you may specify a single transparent color. When nchan=1, trns[0] is transparent gray. When nchan=3, trns[0,1,2] are rgb for transparent color. When nchan=2 or nchan=4, trns is illegal. The png format also allows you to suggest a background color against which your image will look good. (This would be particularly important if your image has transparency, either via an alpha channel or sp_settrans.) When nchan = 1 or 2, bkgd[0] is background gray. When nchan = 3 or 4, trns[0,1,2] are rgb for background color. The png standard mentions the following keywords: "Title", "Author", "Description", "Copyright", "Creation Time", "Software" (program that created the image), "Disclaimer", "Warning", "Source" (device used to create the image), and "Comment". The spng interface supports three additional png chunks: pHYs = pixel dimensions and/or aspect ratio as scanned or printed sCAL = physical scale of subject of image pCAL = mapping from pixel values to physical values Parameter n_xpix or n_ypix is the number of pixels per unit in the horizontal (vertical) direction, and per_meter!=0 indicates that one unit is one meter. If per_meter=0, the unit is unknown, and only the ratio of the vertical to horizontal numbers of pixels is significant. Parameter xpix_sz or ypix_sz is the number of units per pixel and sunit is either SP_METERS or SP_RADIANS. Parameter purpose is a name or description of the calibration, and punit is the units of the physical pixel value for a pCAL mapping. The pCAL defines first a mapping from floating point data values to integer values, and second a mapping from integer values into the specified bit depth of the image to be stored. The integer mapping is as follows: original = original integer (digitized) data x0 <= original <= x1 stored = scaled integer data actually stored in png 0 <= stored <= max = 2^depth-1 stored = (unsigned)(max*((double)original-x0)/(x1-x0) + 0.50000001) The floating point mapping is: the png standard defines four types of floating point maps: original = (int)((physical-p0)*(x1-x0)/p1 + 0.0000001) if type=0 (linear) original = (int)(log((physical-p0)/p1)*(x1-x0)/p2 + 0.0000001) if type=1 (exponential) original = (int)(log((physical-p0)/p1)*(x1-x0)/log(p2) + 0.0000001) if type=2 (exponential alternate form) original = (int)(asinh((physical-p0)/p1)*(x1-x0)/p2 + p3 + 0.0000001) if type=3 (hyperbolic) The spng interface does not support images of less than 8 bits (one char) in memory. You may create png files with depth less than 8 bits, but you must write such files using an image array with at least one byte per pixel. */ yorick-z/ympeg.c0000644000175000017500000003160310313362417013777 0ustar thibautthibaut/* * $Id: ympeg.c,v 1.1.1.1 2005/09/18 22:07:11 dhmunro Exp $ * mpeg encoding interface for yorick */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #include "ydata.h" #include "yio.h" #include "defmem.h" #include "pstdlib.h" #include /* default parameter values */ #define YMPG_BIT_RATE 400000 #define YMPG_FRAME_RATE 24 #define YMPG_GOP_SIZE 10 #define YMPG_MAX_B_FRAMES 1 #ifdef YAVC_SHARED /* -DYAVC_SHARED to dynamically link libavcodec using dlopen */ # include "yio.h" # include "yavcodec.h" # define YAVC_(f) 0 #else /* -UYAVC_SHARED to statically link libavcodec */ # include "avcodec.h" # define YAVC_(f) f #endif static AVCodec *yavc_encoder = YAVC_(&mpeg1video_encoder); static unsigned int (*yavc_version)(void) = YAVC_(avcodec_version); static void (*yavc_init)(void) = YAVC_(avcodec_init); static void (*yavc_register)(AVCodec *format) = YAVC_(register_avcodec); static AVCodec *(*yavc_find_encoder)(enum CodecID id) = YAVC_(avcodec_find_encoder); static AVCodecContext *(*yavc_alloc_context)(void) = YAVC_(avcodec_alloc_context); static AVFrame *(*yavc_alloc_frame)(void) = YAVC_(avcodec_alloc_frame); static int (*yavc_open)(AVCodecContext *avctx, AVCodec *codec) = YAVC_(avcodec_open); static int (*yavc_encode_video)(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVFrame *pict) = YAVC_(avcodec_encode_video); static int (*yavc_close)(AVCodecContext *avctx) = YAVC_(avcodec_close); static void *(*yavc_malloc)(unsigned int size) = YAVC_(av_malloc); static void (*yavc_free)(void *ptr) = YAVC_(av_free); static int (*yavc_fill)(AVPicture *picture, uint8_t *ptr, int pix_fmt, int width, int height) = YAVC_(avpicture_fill); static int (*yavc_get_size)(int pix_fmt, int width, int height) = YAVC_(avpicture_get_size); static int (*yavc_convert)(AVPicture *dst,int dst_pix_fmt,const AVPicture *src, int pix_fmt, int width, int height) = YAVC_(img_convert); /* static int yavc_bld_version = LIBAVCODEC_VERSION_INT; */ static int yavc_lib_version = -1; /*--------------------------------------------------------------------------*/ extern BuiltIn Y_mpeg_create, Y_mpeg_write; typedef struct ympg_stream ympg_stream; typedef struct ympg_block ympg_block; /* implement zlib state as a foreign yorick data type */ struct ympg_stream { int references; /* reference counter */ Operations *ops; /* virtual function table */ FILE *f; AVCodecContext *c; AVCodec *codec; uint8_t *in, *out; AVFrame *frame; long nout, nframes; int width, height, outsize; }; extern ympg_stream *ympg_create(char *filename, long *params); extern void ympg_free(void *ympg); /* ******* Use Unref(ympg) ******* */ extern Operations ympg_ops; extern PromoteOp PromXX; extern UnaryOp ToAnyX, NegateX, ComplementX, NotX, TrueX; extern BinaryOp AddX, SubtractX, MultiplyX, DivideX, ModuloX, PowerX; extern BinaryOp EqualX, NotEqualX, GreaterX, GreaterEQX; extern BinaryOp ShiftLX, ShiftRX, OrX, AndX, XorX; extern BinaryOp AssignX, MatMultX; extern UnaryOp EvalX, SetupX, PrintX; extern MemberOp GetMemberX; static UnaryOp ympg_print; Operations ympg_ops = { &ympg_free, T_OPAQUE, 0, T_STRING, "zlib_stream", {&PromXX, &PromXX, &PromXX, &PromXX, &PromXX, &PromXX, &PromXX, &PromXX}, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &NegateX, &ComplementX, &NotX, &TrueX, &AddX, &SubtractX, &MultiplyX, &DivideX, &ModuloX, &PowerX, &EqualX, &NotEqualX, &GreaterX, &GreaterEQX, &ShiftLX, &ShiftRX, &OrX, &AndX, &XorX, &AssignX, &EvalX, &SetupX, &GetMemberX, &MatMultX, &ympg_print }; /*--------------------------------------------------------------------------*/ /* Set up a block allocator which grabs space for 32 ympg_stream objects * at a time. Since ympg_stream contains an ops pointer, the alignment * of a ympg_stream must be at least as strict as a void*. */ static MemryBlock ympg_mblock = {0, 0, sizeof(ympg_stream), 32*sizeof(ympg_stream)}; static int ympg_initialized = 0; static void ympg_link(void); ympg_stream * ympg_create(char *filename, long *params) { char *name = p_native(filename); FILE *f = (name && name[0])? fopen(name, "w") : 0; ympg_stream *ympg = 0; p_free(name); if (f) { AVCodec *codec; if (params && (params[0]<0 || params[1]<0 || params[2]<0)) YError("mpeg_create: bad parameter list dimensions or values"); if (ympg_initialized != 1) { if (!yavc_convert) ympg_link(); yavc_lib_version = yavc_version(); yavc_init(); yavc_register(yavc_encoder); ympg_initialized = 1; } codec = yavc_find_encoder(CODEC_ID_MPEG1VIDEO); if (codec) { ympg = NextUnit(&ympg_mblock); ympg->references = 0; ympg->ops = &ympg_ops; ympg->f = f; ympg->c = yavc_alloc_context(); /* ffmpeg 0.4.8 bit_rate was first item in AVCodecContext */ if (yavc_lib_version < 0x000409) /* ffmpeg 0.4.8 bit_rate was first item in AVCodecContext */ ympg->c = (void *)&ympg->c->bit_rate; ympg->codec = codec; ympg->frame = yavc_alloc_frame(); ympg->in = ympg->out = 0; ympg->width = ympg->height = ympg->outsize = 0; ympg->nout = ympg->nframes = 0; if (!ympg->c || !ympg->frame) { if (ympg->c) yavc_free(ympg->c); if (ympg->frame) yavc_free(ympg->frame); FreeUnit(&ympg_mblock, ympg); ympg = 0; YError("mpeg_create: yavc_alloc_context or alloc_frame failed"); } else { ympg->c->bit_rate = (params && params[0])? params[0] : YMPG_BIT_RATE; ympg->c->frame_rate = (params && params[1])? params[1] : YMPG_FRAME_RATE; /* note c->frame_rate_base=1 by default, unnecessary for mpeg1? */ ympg->c->gop_size = (params && params[2])? params[2] : YMPG_GOP_SIZE; ympg->c->max_b_frames = (params && params[3]>=0)? params[3] : YMPG_MAX_B_FRAMES; } } else { YError("mpeg_create: failed to find MPEG1VIDEO encoder"); } } else { YError("mpeg_create: fopen failed to create mpeg output file"); } return ympg; } void ympg_free(void *ympgv) /* ******* Use Unref(ympg) ******* */ { ympg_stream *ympg = ympgv; /* get the delayed frames */ if (ympg->f && ympg->nframes) { if (ympg->nout) for (;;) { ympg->nout = yavc_encode_video(ympg->c, ympg->out, ympg->outsize, 0); if (!ympg->nout) break; fwrite(ympg->out, 1, ympg->nout, ympg->f); } /* add sequence end code to mpeg file */ ympg->out[0] = 0x00; ympg->out[1] = 0x00; ympg->out[2] = 0x01; ympg->out[3] = 0xb7; fwrite(ympg->out, 1, 4, ympg->f); } if (ympg->f) fclose(ympg->f); ympg->f = 0; if (ympg->c) { if (!ympg->codec) yavc_close(ympg->c); yavc_free(ympg->c); } ympg->c = 0; if (ympg->out) yavc_free(ympg->out); ympg->out = 0; if (ympg->in) yavc_free(ympg->in); ympg->in = 0; if (ympg->frame) yavc_free(ympg->frame); ympg->frame = 0; FreeUnit(&ympg_mblock, ympg); } /* ARGSUSED */ static void ympg_print(Operand *op) { /* ympg_stream *yzs = op->value; */ ForceNewline(); PrintFunc("mpeg encoder object"); ForceNewline(); } /*--------------------------------------------------------------------------*/ void Y_mpeg_create(int nArgs) { char *filename = (nArgs>=1 && nArgs<=2)? YGetString(sp-nArgs+1) : 0; long bad_params[4] = { -1, -1, -1, -1 }; long *params = 0; if (nArgs == 2) { Dimension *dims = 0; params = YGet_L(sp-nArgs+2, 1, &dims); if (!dims || dims->next || dims->number!=4) params = bad_params; } PushDataBlock(ympg_create(filename, params)); } void Y_mpeg_write(int nArgs) { Operand op; Symbol *stack = sp-nArgs+1; int ndims; Dimension *dims; long idims[3]; uint8_t *image; AVPicture img; int width, height, wyuv, hyuv; ympg_stream *ympg; if (nArgs != 2) YError("mpeg_write takes at exactly 2 arguments"); if (!stack->ops) YError("mpeg_write takes no keywords"); stack->ops->FormOperand(stack, &op); if (op.ops != &ympg_ops) YError("mpeg_write: first argument must be an mpeg encoder object"); ympg = op.value; image = (uint8_t *)YGet_C(stack+1, 0, &dims); ndims = YGet_dims(dims, idims, 3); width = idims[1]; height = idims[2]; if (ndims!=3 || idims[0]!=3 || width<8 || height<8) YError("mpeg_write: image not rgb or too small"); wyuv = (width+7) & ~7; hyuv = (height+7) & ~7; if (ympg->codec) { int size = yavc_get_size(PIX_FMT_YUV420P, wyuv, hyuv); ympg->in = yavc_malloc(size); ympg->outsize = size>100512? size+512 : 100512; ympg->out = yavc_malloc(ympg->outsize); if (!ympg->in || !ympg->out) YError("mpeg_write: av_malloc memory manager failed"); /* note: ffmpeg source routinely casts AVFrame* to AVPicture* */ yavc_fill((AVPicture*)ympg->frame, ympg->in, PIX_FMT_YUV420P, wyuv, hyuv); /* set picture size */ ympg->c->width = wyuv; ympg->c->height = hyuv; if (yavc_open(ympg->c, ympg->codec) < 0) YError("mpeg_create: avcodec_open failed"); ympg->codec = 0; } else if (wyuv!=ympg->c->width || hyuv!=ympg->c->height) { YError("mpeg_write: image dimensions differ from previous frame"); } yavc_fill(&img, image, PIX_FMT_RGB24, width, height); /* note: ffmpeg source routinely casts AVFrame* to AVPicture* */ if (yavc_convert((AVPicture*)ympg->frame, PIX_FMT_YUV420P, &img, PIX_FMT_RGB24, width, height) < 0) YError("mpeg_write: avcodec RGB24 --> YUV420P converter missing"); ympg->nout = yavc_encode_video(ympg->c, ympg->out, ympg->outsize, ympg->frame); while (ympg->nout==ympg->outsize) { fwrite(ympg->out, 1, ympg->nout, ympg->f); ympg->nout = yavc_encode_video(ympg->c, ympg->out, ympg->outsize, 0); } if (ympg->nout) fwrite(ympg->out, 1, ympg->nout, ympg->f); ympg->nframes++; } #ifdef YAVC_SHARED #define NSYMS 15 static struct symadd_t { char *name; int is_data; void *paddr; } ympg_symadd[NSYMS] = {{"mpeg1video_encoder", 1, &yavc_encoder}, {"avcodec_version", 0, &yavc_version}, {"avcodec_init", 0, &yavc_init}, {"register_avcodec", 0, &yavc_register}, {"avcodec_find_encoder", 0, &yavc_find_encoder}, {"avcodec_alloc_context", 0, &yavc_alloc_context}, {"avcodec_alloc_frame", 0, &yavc_alloc_frame}, {"avcodec_open", 0, &yavc_open}, {"avcodec_encode_video", 0, &yavc_encode_video}, {"avcodec_close", 0, &yavc_close}, {"av_malloc", 0, &yavc_malloc}, {"av_free", 0, &yavc_free}, {"avpicture_fill", 0, &yavc_fill}, {"avpicture_get_size", 0, &yavc_get_size}, /* img_convert must be final entry */ {"img_convert", 0, &yavc_convert}}; static void ympg_link(void) { if (!ympg_initialized) { char *yavc_path[] = { 0, 0, "libavcodec", "/lib/libavcodec", "/usr/lib/libavcodec", "/usr/local/lib/libavcodec", "/sw/lib/libavcodec", 0 }; char **yavc_name = yavc_path; char *yavc_env = Ygetenv("Y_LIBAVCODEC"); void *dll = 0; /* look for libavcodec first at name in Y_LIBAVCODEC environment * variable (not including .so or other extension), then Y_HOME/lib, * then as simply "libavcodec" (current working directory?), * then in system places /lib, /usr/lib, /usr/local/lib */ if (yavc_env && yavc_env[0]) yavc_path[0] = yavc_env; else yavc_name++; if (yHomeDir && yHomeDir[0]) { char *yhscan = yHomeDir; while (yhscan[1]) yhscan++; yavc_path[1] = p_strncat(yHomeDir, (yhscan[0]=='/')? "lib/libavcodec" : "/lib/libavcodec", 0); } else { yavc_name++; } for ( ; *yavc_name ; yavc_name++) { dll = p_dlopen(*yavc_name); if (dll) { int i, mask; for (i=0,mask=1 ; i. UCRL-CODE-155996 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the disclaimer below. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the disclaimer (as noted below) in the documentation and/or other materials provided with the distribution. * Neither the name of the UC/LLNL nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Additional BSD Notice 1. This notice is required to be provided under our contract with the U.S. Department of Energy (DOE). This work was produced at the University of California, Lawrence Livermore National Laboratory under Contract No. W-7405-ENG-48 with the DOE. 2. Neither the United States Government nor the University of California nor any of their employees, makes any warranty, express or implied, or assumes any liability or responsibility for the accuracy, completeness, or usefulness of any information, apparatus, product, or process disclosed, or represents that its use would not infringe privately-owned rights. 3. Also, reference herein to any specific commercial products, process, or services by trade name, trademark, manufacturer or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or the University of California. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or the University of California, and shall not be used for advertising or product endorsement purposes. yorick-z/mpgtest.i0000644000175000017500000000116710313362416014350 0ustar thibautthibaut/* * $Id: mpgtest.i,v 1.1.1.1 2005/09/18 22:07:10 dhmunro Exp $ * test yorick mpeg encoder */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ require, "mpeg.i"; require, "movie.i"; if (is_void(_orig_movie)) _orig_movie = movie; require, "demo2.i"; func mpgtest(void) { _mpgtest_name = "test.mpg"; movie = _mpgtest_movie; demo2, 3; } func _mpgtest_movie(__f, __a, __b, __c) { movie = _orig_movie; return mpeg_movie(_mpgtest_name, __f, __a, __b, __c); } yorick-z/yzlib.c0000644000175000017500000004205310313362415014006 0ustar thibautthibaut/* * $Id: yzlib.c,v 1.1.1.1 2005/09/18 22:07:09 dhmunro Exp $ * yorick interface to zlib deflate and inflate functions */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ #include "ydata.h" #include "yio.h" #include "defmem.h" #include "pstdlib.h" #include "play.h" #include #include "zlib.h" extern BuiltIn Y_z_deflate, Y_z_inflate, Y_z_flush, Y_z_setdict, Y_z_crc32; /*--------------------------------------------------------------------------*/ typedef struct yz_stream yz_stream; typedef struct yz_block yz_block; /* implement zlib state as a foreign yorick data type */ struct yz_stream { int references; /* reference counter */ Operations *ops; /* virtual function table */ int status; /* 1 deflate, 2 inflate, 3 inflate/done, 0 ended */ yz_block *chunk; /* output chunks */ Bytef *dict; /* inflate dictionary */ uInt ldict; int need_dict; /* adler valid */ uLong adler; /* checksum for required dictionary */ z_stream zs; /* zlib stream state, see zlib.h */ }; struct yz_block { yz_block *prev; unsigned long used, avail; Byte data[sizeof(long)]; }; extern yz_stream *yz_create(int inflate, int level); extern void yz_free(void *yzs); /* ******* Use Unref(yzs) ******* */ extern Operations yz_ops; extern PromoteOp PromXX; extern UnaryOp ToAnyX, NegateX, ComplementX, NotX, TrueX; extern BinaryOp AddX, SubtractX, MultiplyX, DivideX, ModuloX, PowerX; extern BinaryOp EqualX, NotEqualX, GreaterX, GreaterEQX; extern BinaryOp ShiftLX, ShiftRX, OrX, AndX, XorX; extern BinaryOp AssignX, MatMultX; extern UnaryOp EvalX, SetupX, PrintX; extern MemberOp GetMemberX; static UnaryOp yz_print; Operations yz_ops = { &yz_free, T_OPAQUE, 0, T_STRING, "zlib_stream", {&PromXX, &PromXX, &PromXX, &PromXX, &PromXX, &PromXX, &PromXX, &PromXX}, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &ToAnyX, &NegateX, &ComplementX, &NotX, &TrueX, &AddX, &SubtractX, &MultiplyX, &DivideX, &ModuloX, &PowerX, &EqualX, &NotEqualX, &GreaterX, &GreaterEQX, &ShiftLX, &ShiftRX, &OrX, &AndX, &XorX, &AssignX, &EvalX, &SetupX, &GetMemberX, &MatMultX, &yz_print }; /*--------------------------------------------------------------------------*/ /* Set up a block allocator which grabs space for 32 yz_stream objects * at a time. Since yz_stream contains an ops pointer, the alignment * of a yz_stream must be at least as strict as a void*. */ static MemryBlock yz_mblock = {0, 0, sizeof(yz_stream), 32*sizeof(yz_stream)}; yz_stream * yz_create(int inflate, int level) { int status; yz_stream *yzs = NextUnit(&yz_mblock); yzs->references = 0; yzs->ops = &yz_ops; /* voidpf (*zalloc)(voidpf opaque, uInt items, uInt size) * void (*zfree)(voidpf opaque, voidpf address) * uInt is unsigned int, voidpf is void FAR *, declared in zlib.h */ yzs->zs.zalloc = Z_NULL; yzs->zs.zfree = Z_NULL; yzs->zs.opaque = Z_NULL; yzs->zs.data_type = Z_UNKNOWN; yzs->chunk = 0; yzs->dict = 0; yzs->ldict = 0; yzs->need_dict = 0; yzs->adler = 0; yzs->status = 0; status = inflate? inflateInit(&yzs->zs) : deflateInit(&yzs->zs, level); if (status != Z_OK) { FreeUnit(&yz_mblock, yzs); if (status == Z_STREAM_ERROR) YError("zlib (deflate): invalid compression level"); else if (status == Z_VERSION_ERROR) YError("zlib (deflate/inflate): libz version mismatch"); else if (status == Z_MEM_ERROR) YError("zlib (deflate/inflate): memory error on init"); else YError("zlib (deflate/inflate): unknown error on init"); return 0; } yzs->status = inflate? 2 : 1; return yzs; } static void yz_free_chunk(yz_block *yzbp); void yz_free(void *yzsv) /* ******* Use Unref(yzs) ******* */ { yz_stream *yzs = yzsv; int status; if (!yzs) return; yz_free_chunk(yzs->chunk); yzs->chunk = 0; if (yzs->dict) { p_free(yzs->dict); yzs->dict = 0; } status = yzs->status; yzs->status = 0; if (status == 1) deflateEnd(&yzs->zs); else if (status==2 && status==3) inflateEnd(&yzs->zs); FreeUnit(&yz_mblock, yzs); } static void yz_free_chunk(yz_block *yzb) { if (yzb) { if (yzb->prev) yz_free_chunk(yzb->prev); yzb->prev = 0; p_free(yzb); } } static void yz_print(Operand *op) { yz_stream *yzs = op->value; ForceNewline(); if (yzs->status==1) PrintFunc("zlib deflate buffer object"); else if (yzs->status==2) PrintFunc("zlib inflate buffer object"); else if (yzs->status==3) PrintFunc("zlib finished inflate buffer object"); else PrintFunc("zlib buffer object, (de)compression finished"); ForceNewline(); } static Bytef *yz_getspace(yz_stream *yzs, unsigned long nbytes); static void yz_do_deflate(yz_stream *yzs, Bytef *data, unsigned long ldata, int flush); void Y_z_deflate(int nArgs) { int level = Z_DEFAULT_COMPRESSION; yz_stream *yzs = 0; Bytef *data = 0; unsigned long ldata = 0; if (nArgs > 0) { Operand op; Symbol *stack = sp-nArgs+1; if (nArgs > 2) YError("z_deflate takes at most 2 arguments"); if (!stack->ops) YError("z_deflate takes no keywords"); stack->ops->FormOperand(stack, &op); if (op.ops == &yz_ops) { yzs = op.value; if (yzs->status == 2) YError("z_deflate: cannot use inflate state for deflate call"); else if (yzs->status != 1) YError("z_deflate: deflate buffer closed, compression finished"); } else if (op.value != &nilDB) { level = (int)YGetInteger(stack); } if (nArgs > 1) { stack++; stack->ops->FormOperand(stack, &op); if (op.value != &nilDB) { if (!op.ops->isArray) YError("z_deflate data or dictionary must be an array data type"); if (op.ops==&stringOps || op.ops==&pointerOps) YError("z_deflate cannot handle string or pointer data types"); ldata = op.type.number * op.type.base->size; data = op.value; } } } if (!yzs) { /* create a new zlib state buffer */ yzs = (yz_stream *)PushDataBlock(yz_create(0, level)); if (data) { int flag = deflateSetDictionary(&yzs->zs, data, (uInt)ldata); if (flag != Z_OK) { yzs->status = 0; deflateEnd(&yzs->zs); YError("z_deflate: zlib error setting dictionary"); } else { yzs->adler = yzs->zs.adler; yzs->need_dict = 1; } } } else { /* compress a chunk of data */ long ntotal = 0; yz_block *chunk; yz_do_deflate(yzs, data, ldata, Z_NO_FLUSH); for (chunk=yzs->chunk ; chunk ; chunk=chunk->prev) ntotal += chunk->used; PushLongValue(ntotal>1023? ntotal : 0L); } } void Y_z_flush(int nArgs) { yz_stream *yzs = 0; Bytef *data = 0; unsigned long ldata = 0; StructDef *type = &charStruct; Operand op; long i=0, lbuf, nbytes=0, nitems=0, nextra=0; yz_block *k, *n, *t; Array *array; unsigned char *c; char junk[4]; Symbol *stack = sp-nArgs+1; if (nArgs<1 || nArgs>2) YError("z_flush takes 1 or 2 arguments"); if (!stack->ops) YError("z_flush takes no keywords"); stack->ops->FormOperand(stack, &op); if (op.ops == &yz_ops) { yzs = op.value; if (yzs->status!=1 && yzs->status!=2 && yzs->status!=3) YError("z_flush: zlib buffer closed, stream finished"); } else { YError("z_flush first parameter must be a zlib buffer"); } if (nArgs > 1) { stack++; stack->ops->FormOperand(stack, &op); if (yzs->status == 1) { if (op.ops == &rangeOps) { Range *r = op.value; if (r->nilFlags!=11 || r->inc!=1) YError("z_flush deflate data must be an array data type or -"); data = (Bytef *)junk; } else if (op.value != &nilDB) { if (!op.ops->isArray) YError("z_flush deflate data must be an array data type or -"); if (op.ops==&stringOps || op.ops==&pointerOps) YError("z_flush cannot handle string or pointer data types"); ldata = op.type.number * op.type.base->size; data = op.value; } } else if (op.ops == &structDefOps) { type = op.value; if (!type->dataOps->isArray) YError("z_flush inflate type must be an array data type"); if (type->dataOps==&stringOps || type->dataOps==&pointerOps) YError("z_flush string or pointer type illegal as inflate type"); } else { YError("z_flush illegal inflate type argument"); } } if (yzs->status == 1) { /* deflate final chunk if given */ if (data) yz_do_deflate(yzs, data, ldata, Z_FINISH); } /* reverse list of chunks, count total bytes */ for (n=0,k=yzs->chunk ; k ; n=k,k=t) { nbytes += k->used; t = k->prev; k->prev = n; } yzs->chunk = n; /* extract compressed data to zdata return value */ if (type == &charStruct) { nitems = nbytes; } else if (yzs->status==3) { nitems = (nbytes+type->size-1) / type->size; } else { nitems = nbytes / type->size; nextra = nbytes - type->size*nitems; } array = (Array *)PushDataBlock(NewArray(type, ynew_dim(nitems, (void*)0))); c = (unsigned char *)array->value.c; for (k=t=yzs->chunk ; k ; t=k,k=k->prev) { lbuf = k->prev? k->used : k->used-nextra; for (i=0 ; idata[i]; c += lbuf; } for (lbuf=0 ; lbufchunk->data[lbuf] = t->data[i++]; /* zap all but first chunk */ k = yzs->chunk; k->avail += k->used - nextra; k->used = nextra; for (;;) { t = k->prev; if (!t) break; k->prev = t->prev; p_free(t); } } void Y_z_inflate(int nArgs) { yz_stream *yzs = 0; Bytef *zdata = 0; unsigned long lzdata = 0; Bytef *data = 0; unsigned long ldata = 0; if (nArgs > 0) { Symbol *stack = sp-nArgs+1; Operand op; if (nArgs > 3) YError("z_inflate takes at most 3 arguments"); if (!stack->ops) YError("z_inflate takes no keywords"); stack->ops->FormOperand(stack, &op); if (op.ops == &yz_ops) { yzs = op.value; if (yzs->status == 1) YError("z_inflate: cannot use deflate state for inflate call"); else if (yzs->status != 2) YError("z_inflate: inflate buffer closed, decompression finished"); if (nArgs > 1) { stack++; if (!stack->ops) YError("z_inflate takes no keywords"); stack->ops->FormOperand(stack, &op); if (op.value != &nilDB) { if (op.ops != &charOps) YError("z_inflate zdata must have char data type"); lzdata = op.type.number * op.type.base->size; zdata = op.value; } if (nArgs > 2) { stack++; stack->ops->FormOperand(stack, &op); if (!op.ops->isArray) YError("z_inflate output data must be an array data type"); if (op.ops==&stringOps || op.ops==&pointerOps) YError("z_inflate cannot handle string or pointer output data"); ldata = op.type.number * op.type.base->size; data = op.value; } } } else if (op.value!=&nilDB || nArgs>1) { YError("z_inflate arguments are garbled, see help,z_inflate"); } } if (!yzs) { /* create a new zlib state buffer */ yzs = (yz_stream *)PushDataBlock(yz_create(1, 0)); } else { /* uncompress a chunk of zdata, assuming factor of 2 expansion */ int flag, dict_set=0; unsigned long lguess = (lzdata<<1); char junk[4]; yzs->zs.next_in = zdata? zdata : (Bytef *)junk; yzs->zs.avail_in = lzdata; for (;;) { if (!data) { yzs->zs.next_out = yz_getspace(yzs, lguess); yzs->zs.avail_out = yzs->chunk->avail; } else { yzs->zs.next_out = data; yzs->zs.avail_out = ldata; } flag = inflate(&yzs->zs, Z_NO_FLUSH); if (!data) { yzs->chunk->used += yzs->chunk->avail - yzs->zs.avail_out; yzs->chunk->avail = yzs->zs.avail_out; } if (flag==Z_NEED_DICT && !dict_set) { dict_set = 1; if (yzs->dict) { flag = inflateSetDictionary(&yzs->zs, yzs->dict, yzs->ldict); dict_set = 2; p_free(yzs->dict); yzs->dict = 0; if (flag == Z_OK) continue; dict_set = (flag == Z_DATA_ERROR)? 3 : 4; } else { yzs->adler = yzs->zs.adler; if (inflateReset(&yzs->zs) != Z_OK) dict_set = 5; else yzs->need_dict = 1; } flag = Z_NEED_DICT; /* if dict_set==1 here, yzs->dict==0 and inflateReset succeeded */ } if (flag != Z_OK) { if (flag!=Z_NEED_DICT || dict_set!=1) { yzs->status = 0; inflateEnd(&yzs->zs); if (flag!=Z_STREAM_END && flag!=Z_DATA_ERROR) { if (flag != Z_NEED_DICT) YError("z_inflate: STREAM, MEM, or BUF Z_?_ERROR in inflate"); else if (dict_set == 2) YError("z_inflate: multiple dictionary requests by inflate"); else if (dict_set == 3) YError("z_inflate: wrong dictionary, bad adler32 checksum"); else if (dict_set == 4) YError("z_inflate: zlib error setting dictionary"); else YError("z_inflate: inflateReset failed after Z_NEED_DICT"); flag = Z_MEM_ERROR; /* not reached */ } } break; } if (yzs->zs.avail_out) break; if (data) data = 0; /* difficult to recompute lguess, because we don't know how much * is being help in internal zlib state * - so stick with initial estimate? * - could be very bad if huge compression factor */ } if (flag == Z_STREAM_END) { flag = yzs->zs.avail_in? -1 : 0; yzs->status = 3; } else if (flag == Z_OK) { yz_block *k; for (k=yzs->chunk ; k && !k->used ; k=k->prev); flag = k? 2 : 1; } else if (flag == Z_NEED_DICT) { flag = 3; } else /* if (flag == Z_DATA_ERROR) */ { flag = -2; } PushLongValue((long)flag); } } void Y_z_setdict(int nArgs) { yz_stream *yzs = 0; Operand op; Symbol *stack = sp-nArgs+1; if (nArgs<1 || nArgs>2) YError("z_setdict takes 1 or 2 arguments"); if (!stack->ops) YError("z_setdict takes no keywords"); stack->ops->FormOperand(stack, &op); if (op.ops == &yz_ops) { yzs = op.value; if (yzs->status!=1 && yzs->status!=2) YError("z_setdict: zlib buffer closed, stream finished"); } else { YError("z_setdict first parameter must be a zlib buffer"); } if (nArgs == 1) { if (yzs->need_dict) PushLongValue(yzs->adler); else PushDataBlock(RefNC(&nilDB)); } else if (yzs->need_dict && yzs->status==2) { Bytef *dict = 0; long i, ldict = 0; stack++; stack->ops->FormOperand(stack, &op); if (!op.ops->isArray) YError("z_setdict input data must be an array data type"); if (op.ops==&stringOps || op.ops==&pointerOps) YError("z_setdict cannot handle string or pointer input data"); ldict = op.type.number * op.type.base->size; dict = op.value; yzs->dict = p_malloc(ldict); yzs->ldict = ldict; for (i=0 ; idict[i] = dict[i]; PushIntValue(1); } else { PushIntValue(0); } } void Y_z_crc32(int nArgs) { Operand op; Symbol *stack = sp-nArgs+1; int use_adler32; uLong cksum, ldata; if (nArgs<2 || nArgs>3) YError("z_crc32 takes 2 or 3 arguments"); if (!stack->ops || !stack[1].ops) YError("z_crc32 takes no keywords"); use_adler32 = (nArgs==3 && YGetInteger(stack+2)!=0); if (YNotNil(stack)) cksum = YGetInteger(stack); else cksum = use_adler32? adler32(0L, Z_NULL, 0) : crc32(0L, Z_NULL, 0); stack++; stack->ops->FormOperand(stack, &op); if (!op.ops->isArray) YError("z_crc32 input data must be an array data type"); if (op.ops==&stringOps || op.ops==&pointerOps) YError("z_crc32 cannot handle string or pointer input data"); ldata = op.type.number * op.type.base->size; PushLongValue(use_adler32? adler32(cksum, op.value, ldata) : crc32(cksum, op.value, ldata)); } static void yz_do_deflate(yz_stream *yzs, Bytef *data, unsigned long ldata, int flush) { /* compress final chunk of data, guessing factor of 4 compression */ int flag; unsigned long lguess = (ldata >> 2) + 1; yzs->zs.next_in = data; yzs->zs.avail_in = ldata; for (;;) { yzs->zs.next_out = yz_getspace(yzs, lguess); yzs->zs.avail_out = yzs->chunk->avail; flag = deflate(&yzs->zs, flush); yzs->chunk->used += yzs->chunk->avail - yzs->zs.avail_out; yzs->chunk->avail = yzs->zs.avail_out; if (flag != Z_OK) { yzs->status = 0; deflateEnd(&yzs->zs); if (flag != Z_STREAM_END) { if (flush != Z_FINISH) YError("z_deflate: zlib error during deflate"); else YError("z_flush: zlib error during final deflate"); } break; } if (yzs->zs.avail_out) break; /* difficult to recompute lguess here, because we don't know * how much is held in internal zlib state */ } } static Bytef * yz_getspace(yz_stream *yzs, unsigned long nbytes) { yz_block *chunk; long len; if (yzs->chunk && yzs->chunk->avail>=1024) return (Bytef *)yzs->chunk->data + yzs->chunk->used; len = (( ((nbytes-1)>>12) + 1 ) << 12); chunk = p_malloc(sizeof(yz_block) + len); if (!chunk) return 0; chunk->prev = yzs->chunk; chunk->avail = len + sizeof(long); chunk->used = 0; yzs->chunk = chunk; return (Bytef *)chunk->data; } /*--------------------------------------------------------------------------*/ yorick-z/ztest.i0000644000175000017500000001307010313362417014033 0ustar thibautthibaut/* * $Id: ztest.i,v 1.1.1.1 2005/09/18 22:07:11 dhmunro Exp $ * test yorick zlib interface */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ require, "zlib.i"; func ztest(void) { x = span(-1.5,2.5,100)(,-:1:101); y = span(-2.2,1.8,101)(-:1:100,); dat = bytscl(exp(-abs(x,y)^2), top=255); grow, dat, dat, dat, dat, dat, dat, dat, dat; b = z_deflate(); navail = z_deflate(b, dat); zdat = z_flush(b,-); b = z_inflate(); flag = z_inflate(b, zdat); if (flag) { write, format="FAILURE: simple inflate, flag = %ld\n", flag; } else { udat = z_flush(b); if (sizeof(udat)!=sizeof(dat) || anyof(udat!=dat(*))) write, format="%s\n", "FAILURE: simple inflate, udat != dat"; } zdat1 = z_flush(z_deflate(), dat); if (sizeof(zdat1)!=sizeof(zdat) || anyof(zdat1!=zdat)) write, format="%s\n", "FAILURE: single step deflate on flush"; udat = dat; udat(..) = 0; flag = z_inflate(z_inflate(), zdat, udat); if (flag) write, format="FAILURE: inflate to given array, flag=%ld\n", flag; if (anyof(udat!=dat)) write, format="%s\n", "FAILURE: single inflate, udat != dat"; /* noise makes it ten times harder to compress */ datx = dat + char(2*random(dimsof(dat))); zdat1 = z_flush(z_deflate(), datx); b = z_deflate(); zdat2 = []; for (i=1 ; i<707 ; i+=101) { if (z_deflate(b, datx(,i:i+100)) > 10) { grow, zdat2, z_flush(b); write, format="OK: partial deflate flush, len=%ld\n", sizeof(zdat2); } } grow, zdat2, z_flush(b, datx(,i:i+100)); if (sizeof(zdat2)!=sizeof(zdat1) || anyof(zdat2!=zdat1)) write, format="%s\n", "FAILURE: multiple deflate"; b = z_inflate(); ntot = numberof(zdat1); nchnk = ntot/10; udat2 = []; quiet = 0; for (i=0 ; i ntot) nchnk = ntot - i; flag = z_inflate(b, zdat1(i+1:i+nchnk)); if (!flag) { grow, udat2, z_flush(b); break; } else if (flag == 2) { grow, udat2, z_flush(b); if (!quiet++) write, format="OK: partial inflate flush, len=%ld\n", sizeof(udat2); } else if (flag != 1) { write, format="FAILURE: multiple inflate, flag = %ld\n", flag; } else if (i+nchnk == ntot) { write, format="%s\n", "FAILURE: multiple inflate to complete"; break; } } if (sizeof(udat2)!=sizeof(datx) || anyof(udat2!=datx(*))) write, format="%s\n", "FAILURE: multiple inflate, udat != dat"; /* check compress with level */ zdat2 = z_flush(z_deflate(9), datx); write, format="OK: level 9 size=%ld (default size=%ld)\n", sizeof(zdat2), sizeof(zdat1); udat2 = datx; udat2(..) = 0; flag = z_inflate(z_inflate(), zdat2, udat2); if (flag) write, format="FAILURE: level 9 inflate, flag=%ld\n", flag; if (anyof(udat!=dat)) write, format="%s\n", "FAILURE: level 9 inflate, udat2 != datx"; /* try different data type */ datl = long(datx(*)); zdat2 = z_flush(z_deflate(), datl); write, format="OK: long type size=%ld (char type size=%ld)\n", sizeof(zdat2), sizeof(zdat1); b = z_inflate(); ntot = numberof(zdat2); nchnk = ntot/10; udat2 = []; quiet = 0; for (i=0 ; i ntot) nchnk = ntot - i; flag = z_inflate(b, zdat2(i+1:i+nchnk)); if (!flag) { grow, udat2, z_flush(b, long); break; } else if (flag == 2) { grow, udat2, z_flush(b, long); if (!quiet++) write, format="OK: long inflate flush, len=%ld\n", sizeof(udat2); } else if (flag != 1) { write, format="FAILURE: long inflate, flag = %ld\n", flag; } else if (i+nchnk == ntot) { write, format="%s\n", "FAILURE: long inflate to complete"; break; } } if (structof(udat2) != long) write, format="%s\n", "FAILURE: long inflate, wrong z_flush type"; if (sizeof(udat2)!=sizeof(datl) || anyof(udat2!=datl)) write, format="%s\n", "FAILURE: long inflate, udat2 != datl"; dict = dat(6000:8000); b = z_deflate(,dict); adl = z_setdict(b); zdatd = z_flush(b, dat); write, format="OK: dict size=%ld (default size=%ld)\n", sizeof(zdatd), sizeof(zdat); if (adl != z_crc32(,dict,1)) write, format="%s\n", "FAILURE: dict adler32 checksum doesn't match"; b = z_inflate(); flag = z_inflate(b, zdatd); if (flag == 3) { if (adl != z_setdict(b)) write, format="%s\n", "FAILURE: unexpected dict adler32 checksum"; if (z_setdict(b, dict)) { flag = z_inflate(b, zdatd); if (flag) { write, format="FAILURE: dict inflate, flag = %ld\n", flag; } else { udat = z_flush(b); if (sizeof(udat)!=sizeof(dat) || anyof(udat!=dat(*))) write, format="%s\n", "FAILURE: dict inflate, udat != dat"; } } else { write, format="%s\n", "FAILURE: z_setdict rejected dict"; } } else { write, format="FAILURE: flag=%ld unexpected on dict inflate\n", flag; } b = z_inflate(); flag = z_inflate(b, grow(zdat, char(indgen(5)))); if (flag && flag!=-1) { write, format="FAILURE: extra bytes inflate, flag = %ld\n", flag; } else { if (flag != -1) write, format="%s\n", "FAILURE: did not detect extra bytes on inflate"; udat = z_flush(b); if (sizeof(udat)!=sizeof(dat) || anyof(udat!=dat(*))) write, format="%s\n", "FAILURE: extra bytes inflate, udat != dat"; } zdatbad = zdat; zdatbad(1000) = ~zdatbad(1000); b = z_inflate(); flag = z_inflate(b, zdatbad); if (flag != -2) write, format="%s\n", "FAILURE: did not detect corrupt zdata on inflate"; } yorick-z/jpgtest.i0000644000175000017500000000464010313362414014342 0ustar thibautthibaut/* * $Id: jpgtest.i,v 1.1.1.1 2005/09/18 22:07:08 dhmunro Exp $ * test yorick jpeg interface */ /* Copyright (c) 2005, The Regents of the University of California. * All rights reserved. * This file is part of yorick (http://yorick.sourceforge.net). * Read the accompanying LICENSE file for details. */ require, "jpeg.i"; func jpgtest(&gray, &rgb, keep=) { f = open(Y_SITE+"g/earth.gp"); lines = rdline(f, 2000); lines = lines(where(lines)); tok = strtok(lines, " \t=")(1,); list = where((tok>="0") & (tok<="999999")); lines = lines(list); npal = numberof(lines); pal = array(char, 3, npal); if (sread(lines, pal) != 3*npal) error, "problem reading palette earth.gp"; x = span(-3,4,400)(,-:1:380); y = span(-4,3,380)(-:1:400,); z = (16.-abs(x,y)^2)*sin(1.5*x-y+.5*x*y); zb = bytscl(z, top=npal-1); rgb = pal(,1+zb); gray = bytscl(z, top=255); jpeg_write, "test-gray.jpg", gray; jpeg_write, "test-rgb.jpg", rgb; im = jpeg_read("test-gray.jpg"); dev = (0.+gray-im)(*)(rms); write, format="dflt quality gray rms=%g (expect 0.73)\n", dev; if (!keep) remove, "test-gray.jpg"; im = jpeg_read("test-rgb.jpg"); dev = (0.+rgb-im)(*)(rms); write, format="dflt quality rgb rms=%g (expect 1.67)\n", dev; if (!keep) remove, "test-rgb.jpg"; jpeg_write, "test-gray-hi.jpg", gray, , 100; jpeg_write, "test-rgb-hi.jpg", rgb, "rgb-hi Test Image", 100; com = "test comments"; im = jpeg_read("test-gray-hi.jpg", com); dev = (0.+gray-im)(*)(rms); write, format="100 quality gray rms=%g (expect 0.22)\n", dev; if (!is_void(com)) write, "unexpected comments in test-gray-hi"; if (!keep) remove, "test-gray-hi.jpg"; im = jpeg_read("test-rgb-hi.jpg", com); dev = (0.+rgb-im)(*)(rms); write, format="100 quality rgb rms=%g (expect 0.84)\n", dev; if (numberof(com) != 1) write, format="unexpected comment count = %ld\n", numberof(com); if (com(1) != "rgb-hi Test Image") write, format="unexpected comment = %s\n", com(1); if (!keep) remove, "test-rgb-hi.jpg"; jpeg_write, "test-gray-lo.jpg", gray, , 1; jpeg_write, "test-rgb-lo.jpg", rgb, , 1; im = jpeg_read("test-gray-lo.jpg"); dev = (0.+gray-im)(*)(rms); write, format="1 quality gray rms=%g (expect 10.)\n", dev; if (!keep) remove, "test-gray-lo.jpg"; im = jpeg_read("test-rgb-lo.jpg"); dev = (0.+rgb-im)(*)(rms); write, format="1 quality rgb rms=%g (expect 16.)\n", dev; if (!keep) remove, "test-rgb-lo.jpg"; }