diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/blender/imbuf |
Initial revisionv2.25
Diffstat (limited to 'source/blender/imbuf')
48 files changed, 11164 insertions, 0 deletions
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h new file mode 100644 index 00000000000..ec10c9b39ed --- /dev/null +++ b/source/blender/imbuf/IMB_imbuf.h @@ -0,0 +1,479 @@ +/** + * @mainpage IMB - Imbuf module external interface + * + * @section about About the IMB module + * + * External interface of the IMage Buffer module. This module offers + * import/export of several graphical file formats. It offers the + * ImBuf type as a common structure to refer to different graphical + * file formats, and to enable a uniform way of handling them. + * + * @section issues Known issues with IMB + * + * - imbuf is written in C. + * - Endianness issues are dealt with internally. + * - File I/O must be done externally. The module uses FILE*'s to + * direct input/output. + * - Platform dependency is limited. Some minor patches for + * amiga and Irix are present. A 'posix-compliancy-patch' + * provides the interface to windows. + * + * @section dependencies Dependencies + * + * IMB needs: + * - SDNA module + * The listbase types are used for handling the memory + * management. + * - blenlib module + * blenlib handles guarded memory management in blender-style. + * BLI_winstuff.h makes a few windows specific behaviours + * posix-compliant. + * - avi + * avi defines import/export to the avi format. Only anim.c + * needs this. It uses the following functions: + * - avi_close + * - avi_is_avi + * - avi_print_error + * - avi_open_movie + * - avi_read_frame + * - avi_get_stream + * Additionally, it needs the types from the avi module. + * - external jpeg library + * The jpeg lib defines import/export to the jpeg format. + * only jpeg.c needs these. Used functions are: + * - jpeg_destroy + * - jpeg_resync_to_restart + * - jpeg_set_marker_processor + * - jpeg_read_header + * - jpeg_start_decompress + * - jpeg_abort_decompress + * - jpeg_read_scanlines + * - jpeg_finish_decompress + * - jpeg_std_error + * - jpeg_create_decompress + * - jpeg_stdio_src + * - jpeg_start_compress + * - jpeg_write_marker + * - jpeg_write_scanlines + * - jpeg_finish_compress + * - jpeg_create_compress + * - jpeg_stdio_dest + * - jpeg_set_defaults + * - jpeg_set_quality + * - jpeg_destroy_compress + * Additionally, it needs the types from the jpeg lib. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef IMB_IMBUF_H +#define IMB_IMBUF_H + +struct ImBuf; +struct anim; + +/** + * + * @attention Defined in cmap.c + */ +void cspace(struct ImBuf *ibuf, float mat[][4]); + +/** + * + * @attention Defined in cmap.c + */ +void IMB_freeImBufdata(void); + +/** + * + * @attention Defined in cmap.c + */ +void IMB_applycmap(struct ImBuf *ibuf); + +/** + * + * @attention Defined in cmap.c + */ +short IMB_converttocmap(struct ImBuf *ibuf); + +/** + * + * @attention Defined in cmap.c + */ +int IMB_alpha_to_col0(int new); + +/** + * + * @attention Defined in readimage.c + */ +struct ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags); + +/** + * + * @attention Defined in readimage.c + */ +struct ImBuf *IMB_testiffname(char *naam,int flags); + +/** + * + * @attention Defined in readimage.c + */ +struct ImBuf *IMB_loadiffname(char *naam, int flags); + +/** + * + * @attention Defined in readimage.c + */ +void freezbufImBuf(struct ImBuf * ibuf); + +/** + * + * @attention Defined in allocimbuf.c + */ +void IMB_freeImBuf(struct ImBuf * ibuf); + +/** + * + * @attention Defined in allocimbuf.c + */ +struct ImBuf *IMB_allocImBuf(short x, short y, + unsigned char d, unsigned int flags, + unsigned char bitmap); + +/** + * + * @attention Defined in allocimbuf.c + */ +struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1); + +/** + * + * @attention Defined in allocimbuf.c + */ +short IMB_addzbufImBuf(struct ImBuf * ibuf); + +/** + * + * @attention Defined in allocimbuf.c + */ +void IMB_freecmapImBuf(struct ImBuf * ibuf); + +/** + * + * @attention Defined in rectop.c + */ +void IMB_rectop(struct ImBuf *dbuf, + struct ImBuf *sbuf, + int destx, + int desty, + int srcx, + int srcy, + int width, + int height, + void (*operation)(unsigned int *, unsigned int*, int, int), + int value); + +/** + * + * @attention Defined in rectop.c + */ +void IMB_rectoptot(struct ImBuf *dbuf, + struct ImBuf *sbuf, + void (*operation)(unsigned int *, unsigned int*, int, int), + int value); + +/** + * + * @attention Defined in rectop.c + */ +void IMB_rectcpy(unsigned int *drect, unsigned int *srect, int x, int dummy); + +/** + * Return the length (in frames) of the given @a anim. + */ +int IMB_anim_get_duration(struct anim *anim); + +/** + * + * @attention Defined in anim.c + */ +struct anim * IMB_open_anim(char * name, int ib_flags); +void IMB_close_anim(struct anim * anim); + +/** + * + * @attention Defined in anim.c + */ +struct ImBuf * IMB_anim_absolute(struct anim * anim, int position); + +/** + * + * @attention Defined in anim.c + */ +void IMB_free_anim(struct anim * anim); + +/** + * + * @attention Defined in anim.c + */ +int IMB_isanim(char * name); + +/** + * + * @attention Defined in anim.c + */ +struct ImBuf * IMB_anim_nextpic(struct anim * anim); + + +/** + * + * @attention Defined in antialias.c + */ +void IMB_clever_double (struct ImBuf * ibuf); + +/** + * + * @attention Defined in antialias.c + */ +void IMB_antialias(struct ImBuf * ibuf); + +/** + * + * @attention Defined in filter.c + */ +void IMB_filter(struct ImBuf *ibuf); + +/** + * + * @attention Defined in filter.c + */ +void IMB_filtery(struct ImBuf *ibuf); + +/** + * + * @attention Defined in scaling.c + */ +struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1); + +/** + * + * @attention Defined in scaling.c + */ +struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy); + +/** + * + * @attention Defined in scaling.c + */ +struct ImBuf *IMB_scalefieldImBuf(struct ImBuf *ibuf, short newx, short newy); + +/** + * + * @attention Defined in scaling.c + */ +struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, short newx, short newy); + +/** + * + * @attention Defined in writeimage.c + */ +short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags); + +/** + * This function pointer needs to be initialized to enable + * png writing from the ImBuf library. + * + * @attention Defined in writeimage.c + * @attention See also IMB_png_encode() + */ +extern short (*IMB_fp_png_encode)(struct ImBuf *ibuf, int file, int flags); + +/** + * Encodes a png image from an ImBuf + * + * @attention Defined in png_encode.c + * @attention See also IMB_fp_png_encode + */ +short IMB_png_encode(struct ImBuf *ibuf, int file, int flags); + +/** + * + * @attention Defined in util.c + */ +int IMB_ispic(char *name); + +/** + * + * @attention Defined in divers.c + */ +void IMB_de_interlace(struct ImBuf *ibuf); + +/** + * Change the ordering of the colour bytes pointed to by rect from + * rgba to abgr. size * 4 colour bytes are reordered. + * + * @attention Defined in imageprocess.c + */ +void IMB_convert_rgba_to_abgr(int size, unsigned int *rect); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_scalefastfieldImBuf(struct ImBuf *ibuf, + short newx, + short newy); + +/** + * + * @attention defined in readimage.c + * @deprecated Only here for backwards compatibility of the + * @deprecated plugin system. + */ +struct ImBuf *IMB_loadiffmem(int *mem, int flags); + +/** + * + * @attention defined in readimage.c + * @deprecated Only here for backwards compatibility of the + * @deprecated plugin system. + */ +struct ImBuf *IMB_loadifffile(int file, int flags); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_half_x(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_double_x(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_half_y(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_double_y(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_onethird(struct ImBuf *ibuf1); + +/** + * + * @attention defined in scaling.c + */ +struct ImBuf *IMB_halflace(struct ImBuf *ibuf1); + +/** + * + * @attention defined in dither.c + */ +void IMB_dit2(struct ImBuf * ibuf, short ofs, short bits); + +/** + * + * @attention defined in dither.c + */ +void IMB_dit0(struct ImBuf * ibuf, short ofs, short bits); + +/** Externally used vars: fortunately they do not use funny types */ + +/** + * boolean toggle that tells whether or not to + * scale the colour map in the y-direction. + * + * @attention declared in hamx.c + */ +extern int scalecmapY; + +/** + * This 'matrix' defines the transformation from rgb to bw colour + * maps. You need to do a sort of dot-product for that. It is a matrix + * with fixed coefficients, extracted from some book. + * + * @attention Defined in matrix.h, only included in hamx.c + */ +extern float rgb_to_bw[4][4]; + +/** + * + * @attention Defined in rotate.c + */ +void IMB_flipy(struct ImBuf * ibuf); + +/** + * + * @attention Defined in anim.c + */ +void IMB_init_movie_pointers(void); + +/** + * + * @attention Defined in cspace.c + */ +void IMB_cspace(struct ImBuf *ibuf, float mat[][4]); + +/** + * + * @attention Defined in allocimbuf.c + */ +void IMB_freezbufImBuf(struct ImBuf * ibuf); + +/** + * + * @attention Defined in rectop.c + */ +void IMB_rectfill(unsigned int *drect, unsigned int *srect, int x, int value); + +#endif diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h new file mode 100644 index 00000000000..f674ffaab94 --- /dev/null +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -0,0 +1,155 @@ +/** + * IMB_imbuf_types.h (mar-2001 nzc) + * + * Types needed for using the image buffer. + * + * Imbuf is external code, slightly adapted to live in the Blender + * context. It requires an external jpeg module, and the avi-module + * (also external code) in order to function correctly. + * + * This file contains types and some constants that go with them. Most + * are self-explanatory (e.g. IS_amiga tests whether the buffer + * contains an Amiga-format file). + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef IMB_IMBUF_TYPES_H +#define IMB_IMBUF_TYPES_H + +#include <stdio.h> /* for size_t */ +#include "DNA_listBase.h" /* for ListBase */ +struct _AviMovie; +struct Mdec; + +/* the basic imbuf type */ + +typedef struct ImBuf{ + short x,y; /* breedte in pixels, hoogte in scanlines */ + short skipx; /* breedte in ints om bij volgende scanline te komen */ + unsigned char depth; /* actieve aantal bits/bitplanes */ + unsigned char cbits; /* aantal active bits in cmap */ + unsigned short mincol; + unsigned short maxcol; + int type; /* 0=abgr, 1=bitplanes */ + int ftype; + unsigned int *cmap; /* int array van kleuren */ + unsigned int *rect; /* databuffer */ + unsigned int **planes; /* bitplanes */ + int flags; + int mall; /* wat is er intern gemalloced en mag weer vrijgegeven worden */ + short xorig, yorig; + char name[1023]; + char namenull; + int userflags; + int *zbuf; + void *userdata; + unsigned char *encodedbuffer; + unsigned int encodedsize; + unsigned int encodedbuffersize; +} ImBuf; + +/* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */ +typedef enum { + IB_BITMAPFONT = 1 << 0, + IB_BITMAPDIRTY = 1 << 1 +} ImBuf_userflagsMask; + + +/* From iff.h. This was once moved away by Frank, now Nzc moves it + * back. Such is the way it is... It is a long list of defines, and + * there are a few external defines in the back. Most of the stuff is + * probably imbuf_intern only. This will need to be merged later + * on. */ + +#define IB_rect (1 << 0) +#define IB_planes (1 << 1) +#define IB_cmap (1 << 2) + +#define IB_vert (1 << 4) +#define IB_freem (1 << 6) +#define IB_test (1 << 7) + +#define IB_ttob (1 << 8) +#define IB_subdlta (1 << 9) +#define IB_fields (1 << 11) +#define IB_zbuf (1 << 13) + +#define IB_mem (1 << 14) + +#define AMI (1 << 31) +#define PNG (1 << 30) +#define Anim (1 << 29) +#define TGA (1 << 28) +#define JPG (1 << 27) +#define BMP (1 << 26) + +#define RAWTGA (TGA | 1) + +#define JPG_STD (JPG | (0 << 8)) +#define JPG_VID (JPG | (1 << 8)) +#define JPG_JST (JPG | (2 << 8)) +#define JPG_MAX (JPG | (3 << 8)) +#define JPG_MSK (0xffffff00) + +#define AM_ham (0x0800 | AMI) +#define AM_hbrite (0x0080 | AMI) + +#define C233 1 +#define YUVX 2 +#define HAMX 3 +#define TANX 4 + +#define AN_c233 (Anim | C233) +#define AN_yuvx (Anim | YUVX) +#define AN_hamx (Anim | HAMX) +#define AN_tanx (Anim | TANX) + +#define IS_amiga(x) (x->ftype & AMI) +#define IS_ham(x) ((x->ftype & AM_ham) == AM_ham) +#define IS_hbrite(x) ((x->ftype & AM_hbrite) == AM_hbrite) + +#define IS_anim(x) (x->ftype & Anim) +#define IS_hamx(x) (x->ftype == AN_hamx) +#define IS_tga(x) (x->ftype & TGA) +#define IS_png(x) (x->ftype & PNG) +#define IS_bmp(x) (x->ftype & BMP) + +#define IMAGIC 0732 +#define IS_iris(x) (x->ftype == IMAGIC) + +#define IS_jpg(x) (x->ftype & JPG) +#define IS_stdjpg(x) ((x->ftype & JPG_MSK) == JPG_STD) +#define IS_vidjpg(x) ((x->ftype & JPG_MSK) == JPG_VID) +#define IS_jstjpg(x) ((x->ftype & JPG_MSK) == JPG_JST) +#define IS_maxjpg(x) ((x->ftype & JPG_MSK) == JPG_MAX) + +#endif + diff --git a/source/blender/imbuf/Makefile b/source/blender/imbuf/Makefile new file mode 100644 index 00000000000..66c1f06c870 --- /dev/null +++ b/source/blender/imbuf/Makefile @@ -0,0 +1,37 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# Bounces make to subdirectories. + +SOURCEDIR = source/blender/imbuf +DIRS = intern + +include nan_subdirs.mk diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h new file mode 100644 index 00000000000..f67ffea35c9 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_allocimbuf.h @@ -0,0 +1,51 @@ +/** + * allocimbuf.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_ALLOCIMBUF_H +#define IMB_ALLOCIMBUF_H + +struct ImBuf; + +short imb_addrectImBuf(struct ImBuf * ibuf); +short imb_addplanesImBuf(struct ImBuf *ibuf); + +short imb_addencodedbufferImBuf(struct ImBuf *ibuf); +short imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf); + +void imb_freerectImBuf(struct ImBuf *ibuf); +void imb_freeplanesImBuf(struct ImBuf *ibuf); + +short imb_addcmapImBuf(struct ImBuf *ibuf); + +#endif diff --git a/source/blender/imbuf/intern/IMB_amiga.h b/source/blender/imbuf/intern/IMB_amiga.h new file mode 100644 index 00000000000..a801746a448 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_amiga.h @@ -0,0 +1,44 @@ +/** + * IMB_amiga.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_AMIGA_H +#define IMB_AMIGA_H + +struct ImBuf; + +struct ImBuf *imb_loadamiga(int *iffmem,int flags); +short imb_encodebodyh(struct ImBuf *ibuf, int file); +short imb_encodebodyv(struct ImBuf *ibuf, int file); + +#endif diff --git a/source/blender/imbuf/intern/IMB_bitplanes.h b/source/blender/imbuf/intern/IMB_bitplanes.h new file mode 100644 index 00000000000..ab21a37b774 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_bitplanes.h @@ -0,0 +1,44 @@ +/** + * IMB_bitplanes.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_BITPLANES_H +#define IMB_BITPLANES_H + +struct ImBuf; + +void imb_bptolong(struct ImBuf *ibuf); +void imb_longtobp(struct ImBuf *ibuf); +unsigned int **imb_copyplanelist(struct ImBuf *ibuf); + +#endif diff --git a/source/blender/imbuf/intern/IMB_bmp.h b/source/blender/imbuf/intern/IMB_bmp.h new file mode 100644 index 00000000000..572ea7043ac --- /dev/null +++ b/source/blender/imbuf/intern/IMB_bmp.h @@ -0,0 +1,43 @@ +/** + * IMB_bmp.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_BMP_H +#define IMB_BMP_H + +struct ImBuf; + +int imb_is_a_bmp(void *buf); +struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags); + +#endif diff --git a/source/blender/imbuf/intern/IMB_cmap.h b/source/blender/imbuf/intern/IMB_cmap.h new file mode 100644 index 00000000000..71f44a8ddfe --- /dev/null +++ b/source/blender/imbuf/intern/IMB_cmap.h @@ -0,0 +1,44 @@ +/** + * IMB_cmap.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_CMAP_H +#define IMB_CMAP_H + +struct ImBuf; + +void imb_makecolarray(struct ImBuf *ibuf, unsigned char *mem, short nocols); +void imb_losecmapbits(struct ImBuf *ibuf, unsigned int *coltab); +short *imb_coldeltatab(unsigned char *coltab, short mincol, short maxcol, short cbits); + +#endif diff --git a/source/blender/imbuf/intern/IMB_divers.h b/source/blender/imbuf/intern/IMB_divers.h new file mode 100644 index 00000000000..871a4486572 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_divers.h @@ -0,0 +1,42 @@ +/** + * divers.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_DIVERS_H +#define IMB_DIVERS_H + +struct ImBuf; + +void imb_checkncols(struct ImBuf *ibuf); + +#endif diff --git a/source/blender/imbuf/intern/IMB_filter.h b/source/blender/imbuf/intern/IMB_filter.h new file mode 100644 index 00000000000..5fab0ca51da --- /dev/null +++ b/source/blender/imbuf/intern/IMB_filter.h @@ -0,0 +1,42 @@ +/** + * filter.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_FILTER_H +#define IMB_FILTER_H + +struct ImBuf; + +void imb_filterx(struct ImBuf *ibuf); + +#endif diff --git a/source/blender/imbuf/intern/IMB_ham.h b/source/blender/imbuf/intern/IMB_ham.h new file mode 100644 index 00000000000..87c10fee902 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_ham.h @@ -0,0 +1,42 @@ +/** + * IMB_ham.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_HAM_H +#define IMB_HAM_H + +struct ImBuf; + +short imb_converttoham(struct ImBuf *ibuf); + +#endif diff --git a/source/blender/imbuf/intern/IMB_hamx.h b/source/blender/imbuf/intern/IMB_hamx.h new file mode 100644 index 00000000000..a2b3144982a --- /dev/null +++ b/source/blender/imbuf/intern/IMB_hamx.h @@ -0,0 +1,44 @@ +/** + * IMB_hamx.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_HAMX_H +#define IMB_HAMX_H + +struct ImBuf; + +struct ImBuf *imb_loadanim(int *iffmem, int flags); +short imb_enc_anim(struct ImBuf *ibuf, int file); +void imb_convhamx(struct ImBuf *ibuf, unsigned char coltab[][4], short *deltab); + +#endif diff --git a/source/blender/imbuf/intern/IMB_iff.h b/source/blender/imbuf/intern/IMB_iff.h new file mode 100644 index 00000000000..d227ce9730d --- /dev/null +++ b/source/blender/imbuf/intern/IMB_iff.h @@ -0,0 +1,43 @@ +/** + * IMB_iff.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_IFF_H +#define IMB_IFF_H + +struct ImBuf; + +unsigned short imb_start_iff(struct ImBuf *ibuf, int file); +unsigned short imb_update_iff(int file, int code); + +#endif diff --git a/source/blender/imbuf/intern/IMB_iris.h b/source/blender/imbuf/intern/IMB_iris.h new file mode 100644 index 00000000000..8515b4df40a --- /dev/null +++ b/source/blender/imbuf/intern/IMB_iris.h @@ -0,0 +1,43 @@ +/** + * IMB_iris.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_IRIS_H +#define IMB_IRIS_H + +struct ImBuf; + +struct ImBuf *imb_loadiris(unsigned char *mem, int flags); +short imb_saveiris(struct ImBuf * ibuf, int file, int flags); + +#endif diff --git a/source/blender/imbuf/intern/IMB_jpeg.h b/source/blender/imbuf/intern/IMB_jpeg.h new file mode 100644 index 00000000000..645513d30e3 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_jpeg.h @@ -0,0 +1,45 @@ +/** + * IMB_jpeg.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_JPEG_H +#define IMB_JPEG_H + +struct ImBuf; +struct jpeg_compress_struct; + +int imb_save_jpeg(char * name, struct ImBuf * ibuf, int flags); +struct ImBuf * imb_ibJpegImageFromFilename (char * filename, int flags); +struct ImBuf * imb_ibJpegImageFromMemory (unsigned char * buffer, int size, int flags); + +#endif diff --git a/source/blender/imbuf/intern/IMB_png.h b/source/blender/imbuf/intern/IMB_png.h new file mode 100644 index 00000000000..f7f0fd187b8 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_png.h @@ -0,0 +1,43 @@ +/** + * IMB_png.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_PNG_H +#define IMB_PNG_H + +struct ImBuf; + +int imb_is_a_png(void *buf); +struct ImBuf *imb_png_decode(unsigned char *mem, int size, int flags); + +#endif diff --git a/source/blender/imbuf/intern/IMB_targa.h b/source/blender/imbuf/intern/IMB_targa.h new file mode 100644 index 00000000000..47d54d4140d --- /dev/null +++ b/source/blender/imbuf/intern/IMB_targa.h @@ -0,0 +1,45 @@ +/** + * IMB_targa.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMB_TARGA_H +#define IMB_TARGA_H + +struct ImBuf; + +int imb_is_a_targa(void *buf); + +struct ImBuf *imb_loadtarga(unsigned char *mem, int flags); +short imb_savetarga(struct ImBuf * ibuf, int file, int flags); + +#endif diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile new file mode 100644 index 00000000000..e60e75b6d9a --- /dev/null +++ b/source/blender/imbuf/intern/Makefile @@ -0,0 +1,60 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# + +LIBNAME = imbuf +DIR = $(OCGDIR)/blender/imbuf + +include nan_compile.mk + +ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows")) + CFLAGS += -funsigned-char +endif + +CFLAGS += $(LEVEL_1_C_WARNINGS) + +CPPFLAGS += -I$(NAN_JPEG)/include +CPPFLAGS += -I$(NAN_PNG)/include +CPPFLAGS += -I$(NAN_ZLIB)/include +CPPFLAGS += -I../../include +CPPFLAGS += -I../../blenkernel +CPPFLAGS += -I../../blenlib +CPPFLAGS += -I../../avi +# path to the guarded memory allocator +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include +# This is not really needed, but until /include is cleaned, it must be +# there for proper compilation. +# - No, it is also needed in antialias, for listbase (nzc) +CPPFLAGS += -I../../makesdna +# external interface of this module +CPPFLAGS += -I.. + diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c new file mode 100644 index 00000000000..8d9eb17c9c2 --- /dev/null +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -0,0 +1,357 @@ +/** + * allocimbuf.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* It's become a bit messy... Basically, only the IMB_ prefixed files + * should remain. */ + +#include "IMB_imbuf_types.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf.h" + +#include "IMB_divers.h" +#include "IMB_allocimbuf.h" + +static unsigned int dfltcmap[16] = { + 0x00000000, 0xffffffff, 0x777777ff, 0xccccccff, + 0xcc3344ff, 0xdd8844ff, 0xccdd44ff, 0x888833ff, + 0x338844ff, 0x44dd44ff, 0x44ddccff, 0x3388ccff, + 0x8888ddff, 0x4433ccff, 0xcc33ccff, 0xcc88ddff +}; + +void imb_freeplanesImBuf(struct ImBuf * ibuf) +{ + if (ibuf==0) return; + if (ibuf->planes){ + if (ibuf->mall & IB_planes) free(ibuf->planes); + } + ibuf->planes = 0; + ibuf->mall &= ~IB_planes; +} + + +void imb_freerectImBuf(struct ImBuf * ibuf) +{ + if (ibuf==0) return; + if (ibuf->rect){ + if (ibuf->mall & IB_rect) free(ibuf->rect); + } + ibuf->rect=0; + ibuf->mall &= ~IB_rect; +} + +static void freeencodedbufferImBuf(struct ImBuf * ibuf) +{ + if (ibuf==0) return; + if (ibuf->encodedbuffer){ + if (ibuf->mall & IB_mem) free(ibuf->encodedbuffer); + } + ibuf->encodedbuffer = 0; + ibuf->encodedbuffersize = 0; + ibuf->encodedsize = 0; + ibuf->mall &= ~IB_mem; +} + +void IMB_freezbufImBuf(struct ImBuf * ibuf) +{ + if (ibuf==0) return; + if (ibuf->zbuf){ + if (ibuf->mall & IB_zbuf) free(ibuf->zbuf); + } + ibuf->zbuf=0; + ibuf->mall &= ~IB_zbuf; +} + +void IMB_freecmapImBuf(struct ImBuf * ibuf) +{ + if (ibuf == 0) return; + if (ibuf->cmap){ + if (ibuf->mall & IB_cmap) free(ibuf->cmap); + } + ibuf->cmap = 0; + ibuf->mall &= ~IB_cmap; +} + + +void IMB_freeImBuf(struct ImBuf * ibuf) +{ + if (ibuf){ + imb_freeplanesImBuf(ibuf); + imb_freerectImBuf(ibuf); + IMB_freezbufImBuf(ibuf); + IMB_freecmapImBuf(ibuf); + freeencodedbufferImBuf(ibuf); + free(ibuf); + } +} + + +static short addzbufImBuf(struct ImBuf * ibuf) +{ + int size; + + if (ibuf==0) return(FALSE); + IMB_freezbufImBuf(ibuf); + + size = ibuf->x * ibuf->y * sizeof(unsigned int); + if (ibuf->zbuf = MEM_mallocN(size, "addzbufImBuf")){ + ibuf->mall |= IB_zbuf; + return (TRUE); + } + + return (FALSE); +} + + +short imb_addencodedbufferImBuf(struct ImBuf * ibuf) +{ + if (ibuf==0) return(FALSE); + + freeencodedbufferImBuf(ibuf); + + if (ibuf->encodedbuffersize == 0) + ibuf->encodedbuffersize = 10000; + + ibuf->encodedsize = 0; + + if (ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf")){ + ibuf->mall |= IB_mem; + return (TRUE); + } + + return (FALSE); +} + + +short imb_enlargeencodedbufferImBuf(struct ImBuf * ibuf) +{ + unsigned int newsize, encodedsize; + void *newbuffer; + + if (ibuf==0) return(FALSE); + + if (ibuf->encodedbuffersize < ibuf->encodedsize) { + printf("imb_enlargeencodedbufferImBuf: error in parameters\n"); + return(FALSE); + } + + newsize = 2 * ibuf->encodedbuffersize; + if (newsize < 10000) newsize = 10000; + + newbuffer = MEM_mallocN(newsize, "enlargeencodedbufferImBuf"); + if (newbuffer == NULL) return(FALSE); + + if (ibuf->encodedbuffer) { + memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize); + } else { + ibuf->encodedsize = 0; + } + + encodedsize = ibuf->encodedsize; + + freeencodedbufferImBuf(ibuf); + + ibuf->encodedbuffersize = newsize; + ibuf->encodedsize = encodedsize; + ibuf->encodedbuffer = newbuffer; + ibuf->mall |= IB_mem; + + return (TRUE); +} + + +short imb_addrectImBuf(struct ImBuf * ibuf) +{ + int size; + + if (ibuf==0) return(FALSE); + imb_freerectImBuf(ibuf); + + size = ibuf->x * ibuf->y * sizeof(unsigned int); + if (ibuf->rect = MEM_mallocN(size, "imb_addrectImBuf")){ + ibuf->mall |= IB_rect; + if (ibuf->depth > 32) return (addzbufImBuf(ibuf)); + else return (TRUE); + } + + return (FALSE); +} + + +short imb_addcmapImBuf(struct ImBuf *ibuf) +{ + int min; + + if (ibuf==0) return(FALSE); + IMB_freecmapImBuf(ibuf); + + imb_checkncols(ibuf); + if (ibuf->maxcol == 0) return (TRUE); + + if (ibuf->cmap = MEM_callocN(sizeof(unsigned int) * ibuf->maxcol, "imb_addcmapImBuf")){ + min = ibuf->maxcol * sizeof(unsigned int); + if (min > sizeof(dfltcmap)) min = sizeof(dfltcmap); + memcpy(ibuf->cmap, dfltcmap, min); + ibuf->mall |= IB_cmap; + return (TRUE); + } + + return (FALSE); +} + + +short imb_addplanesImBuf(struct ImBuf *ibuf) +{ + int size; + short skipx,d,y; + unsigned int **planes; + unsigned int *point2; + + if (ibuf==0) return(FALSE); + imb_freeplanesImBuf(ibuf); + + skipx = ((ibuf->x+31) >> 5); + ibuf->skipx=skipx; + y=ibuf->y; + d=ibuf->depth; + + planes = MEM_mallocN( (d*skipx*y)*sizeof(int) + d*sizeof(int *), "imb_addplanesImBuf"); + + ibuf->planes = planes; + if (planes==0) return (FALSE); + + point2 = (unsigned int *)(planes+d); + size = skipx*y; + + for (;d>0;d--){ + *(planes++) = point2; + point2 += size; + } + ibuf->mall |= IB_planes; + + return (TRUE); +} + + +struct ImBuf *IMB_allocImBuf(short x,short y,uchar d,unsigned int flags,uchar bitmap) +{ + struct ImBuf *ibuf; + + ibuf = MEM_callocN(sizeof(struct ImBuf), "ImBuf_struct"); + if (bitmap) flags |= IB_planes; + + if (ibuf){ + ibuf->x=x; + ibuf->y=y; + ibuf->depth=d; + ibuf->ftype=TGA; + + if (flags & IB_rect){ + if (imb_addrectImBuf(ibuf)==FALSE){ + IMB_freeImBuf(ibuf); + return (0); + } + } + + if (flags & IB_zbuf){ + if (addzbufImBuf(ibuf)==FALSE){ + IMB_freeImBuf(ibuf); + return (0); + } + } + + if (flags & IB_planes){ + if (imb_addplanesImBuf(ibuf)==FALSE){ + IMB_freeImBuf(ibuf); + return (0); + } + } + } + return (ibuf); +} + + +struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2, tbuf; + int flags = 0; + int x, y; + + if (ibuf1 == 0) return (0); + + if (ibuf1->rect) flags |= IB_rect; + if (ibuf1->planes) flags |= IB_planes; + + x = ibuf1->x; + y = ibuf1->y; + if (ibuf1->flags & IB_fields) y *= 2; + + ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags, 0); + if (ibuf2 == 0) return (0); + + if (flags & IB_rect) memcpy(ibuf2->rect,ibuf1->rect,x * y * sizeof(int)); + if (flags & IB_planes) memcpy(*(ibuf2->planes),*(ibuf1->planes),ibuf1->depth * ibuf1->skipx * y * sizeof(int)); + + if (ibuf1->encodedbuffer) { + ibuf2->encodedbuffersize = ibuf1->encodedbuffersize; + if (imb_addencodedbufferImBuf(ibuf2) == FALSE) { + IMB_freeImBuf(ibuf2); + return(0); + } + + memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize); + } + + + tbuf = *ibuf1; + + // pointers goedzetten + tbuf.rect = ibuf2->rect; + tbuf.planes = ibuf2->planes; + tbuf.cmap = ibuf2->cmap; + tbuf.encodedbuffer = ibuf2->encodedbuffer; + + // malloc flag goed zetten + tbuf.mall = ibuf2->mall; + + *ibuf2 = tbuf; + + if (ibuf1->cmap){ + imb_addcmapImBuf(ibuf2); + if (ibuf2->cmap) memcpy(ibuf2->cmap,ibuf1->cmap,ibuf2->maxcol * sizeof(int)); + } + + return(ibuf2); +} diff --git a/source/blender/imbuf/intern/amiga.c b/source/blender/imbuf/intern/amiga.c new file mode 100644 index 00000000000..ba699f90847 --- /dev/null +++ b/source/blender/imbuf/intern/amiga.c @@ -0,0 +1,536 @@ +/** + * amiga.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_cmap.h" +#include "IMB_allocimbuf.h" +#include "IMB_bitplanes.h" +#include "IMB_amiga.h" + +/* actually hard coded endianness */ +#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) +#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0]) +#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff)) +#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff)) + +/* more endianness... should move to a separate file... */ +#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +#define GET_ID GET_BIG_LONG +#define LITTLE_LONG SWAP_LONG +#else +#define GET_ID GET_LITTLE_LONG +#define LITTLE_LONG ENDIAN_NOP +#endif + +static uchar *decodebodyscanl(uchar *body, short bytes, uchar **list, short d) +{ + for (;d>0;d--){ + uchar *point; + short todo; + uchar i,j; + + point = *(list++); + todo=bytes; + while (todo>0){ + i = *body++; + + if (i & 128){ /* fill */ + if (i==128) continue; /* nop */ + + i=257-i; + todo-=i; + j = *(body++); + do{ + *(point++) = j; + i--; + }while (i); + } else{ /* copy */ + i++; + todo-=i; + + do{ + *(point++) = *(body++); + i--; + }while (i); + } + } + if (todo) return (0); + } + return(body); +} + + +static uchar *decodebodyh(struct ImBuf *ibuf, uchar *body) +{ + if (ibuf->y==1) { + body=decodebodyscanl(body, WIDTHB(ibuf->x), (uchar **)ibuf->planes, ibuf->depth); + } + else { + unsigned int **list; + short skipx,i,bytes,y; + + list = imb_copyplanelist(ibuf); + if (list == 0) return (0); + + y=ibuf->y; + bytes = WIDTHB(ibuf->x); + skipx = ibuf->skipx; + + for (;y>0;y--){ + body=decodebodyscanl(body, bytes, (uchar **)list, ibuf->depth); + if (body == 0) return (0); + + for (i=ibuf->depth-1;i>=0;i--){ + list[i] += skipx; + } + } + free(list); + } + return(body); +} + + +static uchar *decodebodykolum(uchar *body, short bytes, uchar **list, short d, int next) +{ + for (;d>0;d--){ + uchar *point; + short todo; + uchar i,j; + + point = *(list++); + todo=bytes; + while (todo>0){ + i = *body++; + + if (i & 128){ /* fill */ + if (i==128) continue; /* nop */ + + i=257-i; + todo-=i; + j = *body++; + do{ + *point = j; + point += next; + i--; + }while (i); + } + else{ /* copy */ + i++; + todo-=i; + + do{ + *point = *body++; + point += next; + i--; + }while (i); + } + } + if (todo) return (0); + } + return(body); +} + + +static uchar *decodebodyv(struct ImBuf *ibuf, uchar *body) +{ + uchar **list; + short skipx,i,bytes,times; + + list = (uchar **)imb_copyplanelist(ibuf); + if (list == 0) return (0); + + bytes = ibuf->y; + times = WIDTHB(ibuf->x); + skipx = ibuf->skipx << 2; + + for (;times>0;times--){ + body=decodebodykolum(body,bytes,list,ibuf->depth,skipx); + if (body == 0) return (0); + + for (i=ibuf->depth-1;i>=0;i--){ + list[i] += 1; + } + } + free(list); + return(body); +} + +static uchar *makebody(uchar **planes, short bytes, short depth, uchar *buf) +{ + uchar *bitplstart,*temp; + + register uchar last,this,*bitpl; + register short todo; + register int copy; + + bytes--; + for (;depth>0;depth--){ + bitpl = *(planes++); + bitplstart = bitpl; + todo = bytes; + last = *bitpl++; + this = *bitpl++; + copy = last^this; + while (todo>0){ + + if (copy){ + do{ + last = this; + this = *bitpl++; + if (last == this){ + if (this == bitpl[-3]){ /* drie dezelfde? */ + todo -= 1; /* todo goed zetten */ + break; + } + } + }while (--todo != 0); + + copy=bitpl-bitplstart; + copy -= 1; + if (todo) copy -= 2; + + temp = bitpl; + bitpl = bitplstart; + + while (copy){ + last = copy; + if (copy>MAXDAT) last = MAXDAT; + copy -= last; + *buf++ = last-1; + do{ + *buf++ = *bitpl++; + }while(--last != 0); + } + bitplstart = bitpl; + bitpl = temp; + last = this; + + copy = FALSE; + } + else{ + while (*bitpl++ == this){ /* zoek naar eerste afwijkende byte */ + if (--todo == 0) break; /* of einde regel */ + } + bitpl -= 1; + copy = bitpl-bitplstart; + bitplstart = bitpl; + todo -= 1; + this = *bitpl++; + + while (copy){ + if (copy>MAXRUN){ + *buf++ = -(MAXRUN-1); + *buf++ = last; + copy -= MAXRUN; + } + else{ + *buf++ = -(copy-1); + *buf++ = last; + break; + } + } + copy=TRUE; + } + } + } + return (buf); +} + + +short imb_encodebodyh(struct ImBuf *ibuf, int file) +{ + uchar *buf, *endbuf, *max; + int size, line, ok = TRUE; + unsigned int **list; + short skipx,i,y; + + line = WIDTHB(ibuf->x) * ibuf->depth; + line += (line >> 6) + 10; + size = 16 * line; + if (size < 16384) size = 16384; + + buf = (uchar *) malloc(size); + if (buf == 0) return (0); + + max = buf + size - line; + + list = imb_copyplanelist(ibuf); + if (list == 0){ + free(buf); + return (0); + } + + y=ibuf->y; + skipx = ibuf->skipx; + endbuf = buf; + + for (y=ibuf->y;y>0;y--){ + endbuf = makebody((uchar **)list, WIDTHB(ibuf->x), ibuf->depth, endbuf); + if (endbuf==0){ + ok = -20; + break; + } + if (endbuf >= max || y == 1){ + size = endbuf-buf; + if (write(file,buf,size)!=size) ok = -19; + endbuf = buf; + } + for (i=ibuf->depth-1;i>=0;i--){ + list[i] += skipx; + } + if (ok != TRUE) break; + } + free(list); + + free(buf); + return(ok); +} + + +short imb_encodebodyv(struct ImBuf *ibuf, int file) +{ + struct ImBuf *ibufv; + uchar *buf,*endbuf; + short x,offset; + + buf = (uchar *) malloc((ibuf->y + (ibuf->y >> 6) + 10) * ibuf->depth); + if (buf == 0) return (0); + + ibufv=IMB_allocImBuf((ibuf->y)<<3,1, ibuf->depth, 0, 1); + if (ibufv == 0){ + free(buf); + return (0); + } + + offset=0; + + for(x = WIDTHB(ibuf->x);x>0;x--){ + register short i; + + for(i = ibuf->depth-1 ;i>=0;i--){ + register uchar *p1,*p2; + register int skipx; + register short y; + + skipx = (ibuf->skipx)*sizeof(int *); + p1=(uchar *)ibuf->planes[i]; + p2=(uchar *)ibufv->planes[i]; + p1 += offset; + + for (y=ibuf->y;y>0;y--){ + *(p2++) = *p1; + p1 += skipx; + } + } + offset += 1; + + endbuf=makebody((uchar **)ibufv->planes, ibuf->y, ibuf->depth, buf); + if (endbuf==0) return (-20); + if (write(file,buf,endbuf-buf)!=endbuf-buf) return (-19); + } + free(buf); + IMB_freeImBuf(ibufv); + return (TRUE); +} + +static uchar *readbody(struct ImBuf *ibuf, uchar *body) +{ + int skipbuf,skipbdy,depth,y,offset = 0; + + skipbuf = ibuf->skipx; + skipbdy = WIDTHB(ibuf->x); + + for (y = ibuf->y; y> 0; y--){ + for( depth = 0; depth < ibuf->depth; depth ++){ + memcpy(ibuf->planes[depth] + offset, body, skipbdy); + body += skipbdy; + } + offset += skipbuf; + } + return body; +} + +struct ImBuf *imb_loadamiga(int *iffmem,int flags) +{ + int chunk,totlen,len,*cmap=0,cmaplen,*mem,ftype=0; + uchar *body=0; + struct BitMapHeader bmhd; + struct ImBuf *ibuf=0; + + mem = iffmem; + bmhd.w = 0; + + if (GET_ID(mem) != FORM) return (0); + if (GET_ID(mem+2) != ILBM) return (0); + totlen= (GET_BIG_LONG(mem+1) + 1) & ~1; + mem += 3; + totlen -= 4; + + + while(totlen > 0){ + chunk = GET_ID(mem); + len= (GET_BIG_LONG(mem+1) + 1) & ~1; + mem += 2; + + totlen -= len+8; + + switch (chunk){ + case BMHD: + memcpy(&bmhd, mem, sizeof(struct BitMapHeader)); + + bmhd.w = BIG_SHORT(bmhd.w); + bmhd.h = BIG_SHORT(bmhd.h); + bmhd.x = BIG_SHORT(bmhd.x); + bmhd.y = BIG_SHORT(bmhd.y); + bmhd.transparentColor = BIG_SHORT(bmhd.transparentColor); + bmhd.pageWidth = BIG_SHORT(bmhd.pageWidth); + bmhd.pageHeight = BIG_SHORT(bmhd.pageHeight); + + break; + case BODY: + body = (uchar *)mem; + break; + case CMAP: + cmap = mem; + cmaplen = len/3; + break; + case CAMG: + ftype = GET_BIG_LONG(mem); + break; + } + mem = (int *)((uchar *)mem +len); + if (body) break; + } + if (bmhd.w == 0) return (0); + if (body == 0) return (0); + + if (flags & IB_test) ibuf = IMB_allocImBuf(bmhd.w, bmhd.h, bmhd.nPlanes, 0, 0); + else ibuf = IMB_allocImBuf(bmhd.w, bmhd.h, bmhd.nPlanes + (bmhd.masking & 1),0,1); + + if (ibuf == 0) return (0); + + ibuf->ftype = (ftype | AMI); + + if (cmap){ + ibuf->mincol = 0; + ibuf->maxcol = cmaplen; + imb_addcmapImBuf(ibuf); + /* this functions needs a 3rd arg: the number of + * columns.... why did this work before? */ +/* imb_makecolarray(ibuf, cmap); */ + imb_makecolarray(ibuf, cmap, 0); + } + + if (flags & IB_test){ + if (flags & IB_freem) free(iffmem); + return(ibuf); + } + + switch (bmhd.compression){ + case 0: + body= readbody(ibuf, body); + break; + case 1: + body= decodebodyh(ibuf,body); + break; + case 2: + body= decodebodyv(ibuf,body); + ibuf->type |= IB_subdlta; + break; + } + + if (flags & IB_freem) free(iffmem); + + if (body == 0){ + free (ibuf); + return(0); + } + + /* vergeet stencil */ + ibuf->depth = bmhd.nPlanes; + + if (flags & IB_rect){ + imb_addrectImBuf(ibuf); + imb_bptolong(ibuf); + imb_freeplanesImBuf(ibuf); + if (ibuf->cmap){ + if ((flags & IB_cmap) == 0) IMB_applycmap(ibuf); + } else if (ibuf->depth == 18){ + int i,col; + unsigned int *rect; + + rect = ibuf->rect; + for(i=ibuf->x * ibuf->y ; i>0 ; i--){ + col = *rect; + col = ((col & 0x3f000) << 6) + ((col & 0xfc0) << 4) + ((col & 0x3f) << 2); + col += (col & 0xc0c0c0) >> 6; + *rect++ = col; + } + ibuf->depth = 24; + } else if (ibuf->depth <= 8) { /* geen colormap en geen 24 bits: zwartwit */ + uchar *rect; + int size, shift; + + if (ibuf->depth < 8){ + rect = (uchar *) ibuf->rect; + rect += 3; + shift = 8 - ibuf->depth; + for (size = ibuf->x * ibuf->y; size > 0; size --){ + rect[0] <<= shift; + rect += 4; + } + } + rect = (uchar *) ibuf->rect; + for (size = ibuf->x * ibuf->y; size > 0; size --){ + rect[1] = rect[2] = rect[3]; + rect += 4; + } + ibuf->depth = 8; + } + } + + if ((flags & IB_ttob) == 0) IMB_flipy(ibuf); + + if (ibuf) { + if (ibuf->rect) + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + } + + return (ibuf); +} diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c new file mode 100644 index 00000000000..9525fe4ab5f --- /dev/null +++ b/source/blender/imbuf/intern/anim.c @@ -0,0 +1,1157 @@ +/** + * anim.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef _WIN32 +#define INC_OLE2 +#include <windows.h> +#include <windowsx.h> +#include <mmsystem.h> +#include <memory.h> +#include <commdlg.h> +#include <vfw.h> + +#undef AVIIF_KEYFRAME // redefined in AVI_avi.h +#undef AVIIF_LIST // redefined in AVI_avi.h + +#define FIXCC(fcc) if (fcc == 0) fcc = mmioFOURCC('N', 'o', 'n', 'e'); \ + if (fcc == BI_RLE8) fcc = mmioFOURCC('R', 'l', 'e', '8'); +#endif + +#include <sys/types.h> +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#ifndef _WIN32 +#include <dirent.h> +#else +#include <io.h> +#include "BLI_winstuff.h" +#endif + +#include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail + BLI_countlist BLI_stringdec */ + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "AVI_avi.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_bitplanes.h" + + +/* actually hard coded endianness */ +#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) +#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0]) +#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff)) +#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff)) + +/* more endianness... should move to a separate file... */ +#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +#define GET_ID GET_BIG_LONG +#define LITTLE_LONG SWAP_LONG +#else +#define GET_ID GET_LITTLE_LONG +#define LITTLE_LONG ENDIAN_NOP +#endif + +/****/ + +typedef struct Anhd{ + unsigned char type, mask; + unsigned short w, h; + unsigned short x, y; + unsigned short abs16, abs, reala6, real; + unsigned char interleave, pad0; + unsigned short bits16, bits; + unsigned char pad[16]; +}Anhd; + +typedef struct Anim5Delta { + struct Anim5Delta * next, * prev; + void * data; + int type; +}Anim5Delta; + +#define ANIM_NONE (0) +#define ANIM_SEQUENCE (1 << 0) +#define ANIM_DIR (1 << 1) +#define ANIM_ANIM5 (1 << 2) +#define ANIM_TGA (1 << 3) +#define ANIM_MOVIE (1 << 4) +#define ANIM_MDEC (1 << 5) +#define ANIM_AVI (1 << 6) + +#define ANIM5_MMAP 0 +#define ANIM5_MALLOC 1 +#define ANIM5_SNGBUF 2 +#define ANIM5_XOR 4 + +#define MAXNUMSTREAMS 50 + +struct anim { + int ib_flags; + int curtype; + int curposition; /* index 0 = 1e, 1 = 2e, enz. */ + int duration; + int x, y; + + /* voor op nummer */ + char name[256]; + /* voor sequence */ + char first[256]; + + /* anim5 */ + struct ListBase anim5base; + void * anim5mmap; + int anim5len; + struct Anim5Delta *anim5curdlta; + void (*anim5decode)(struct ImBuf *, unsigned char *); + int anim5flags; + + /* movie */ + void *movie; + void *track; + void *params; + int orientation; + size_t framesize; + int interlacing; + + /* data */ + struct ImBuf * ibuf1, * ibuf2; + + /* avi */ + struct _AviMovie *avi; + +#ifdef _WIN32 + /* windows avi */ + int avistreams; + int firstvideo; + int pfileopen; + PAVIFILE pfile; + PAVISTREAM pavi[MAXNUMSTREAMS]; // the current streams + PGETFRAME pgf; +#endif +}; + +/****/ + +#ifdef __sgi + +#include <dmedia/moviefile.h> + +static void movie_printerror(char * str) { + const char * errstr = mvGetErrorStr(mvGetErrno()); + + if (str) { + if (errstr) printf("%s: %s\n", str, errstr); + else printf("%s: returned error\n", str); + } else printf("%s\n", errstr); +} + +static int startmovie(struct anim * anim) { + if (anim == 0) return(-1); + + if ( mvOpenFile (anim->name, O_BINARY|O_RDONLY, &anim->movie ) != DM_SUCCESS ) { + printf("Can't open movie: %s\n", anim->name); + return(-1); + } + if ( mvFindTrackByMedium (anim->movie, DM_IMAGE, &anim->track) != DM_SUCCESS ) { + printf("No image track in movie: %s\n", anim->name); + mvClose(anim->movie); + return(-1); + } + + anim->duration = mvGetTrackLength (anim->track); + anim->params = mvGetParams( anim->track ); + + anim->x = dmParamsGetInt( anim->params, DM_IMAGE_WIDTH); + anim->y = dmParamsGetInt( anim->params, DM_IMAGE_HEIGHT); + anim->interlacing = dmParamsGetEnum (anim->params, DM_IMAGE_INTERLACING); + anim->orientation = dmParamsGetEnum (anim->params, DM_IMAGE_ORIENTATION); + anim->framesize = dmImageFrameSize(anim->params); + + anim->curposition = 0; + + /*printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/ + return (0); +} + +static ImBuf * movie_fetchibuf(struct anim * anim, int position) { + ImBuf * ibuf; +/* extern rectcpy(); */ + int size; + unsigned int *rect1, *rect2; + + if (anim == 0) return (0); + + ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0); + + if ( mvReadFrames(anim->track, position, 1, ibuf->x * ibuf->y * + sizeof(int), ibuf->rect ) != DM_SUCCESS ) { + movie_printerror("mvReadFrames"); + IMB_freeImBuf(ibuf); + return(0); + } + + /* + if (anim->interlacing == DM_IMAGE_INTERLACED_EVEN) + { + rect1 = ibuf->rect + (ibuf->x * ibuf->y) - 1; + rect2 = rect1 - ibuf->x; + + for (size = ibuf->x * (ibuf->y - 1); size > 0; size--){ + *rect1-- = *rect2--; + } + } + */ + + if (anim->interlacing == DM_IMAGE_INTERLACED_EVEN) + { + rect1 = ibuf->rect; + rect2 = rect1 + ibuf->x; + + for (size = ibuf->x * (ibuf->y - 1); size > 0; size--){ + *rect1++ = *rect2++; + } + } + /*if (anim->orientation == DM_TOP_TO_BOTTOM) IMB_flipy(ibuf);*/ + + + return(ibuf); +} + +static void free_anim_movie(struct anim * anim) { + if (anim == NULL) return; + + if (anim->movie) { + mvClose(anim->movie); + anim->movie = NULL; + } + anim->duration = 0; +} + +static int ismovie(char *name) { + return (mvIsMovieFile(name) == DM_TRUE); +} + +#else + +static int ismovie(char *name) { + return 0; +} + + /* never called, just keep the linker happy */ +static int startmovie(struct anim * anim) { return 1; } +static ImBuf * movie_fetchibuf(struct anim * anim, int position) { return NULL; } +static void free_anim_movie(struct anim * anim) { ; } + +#endif + +static int an_stringdec(char *string, char* kop, char *staart,unsigned short *numlen) { + unsigned short len,nums,nume; + short i,found=FALSE; + + len=strlen(string); + + for(i=len-1;i>=0;i--){ + if (string[i]=='/') break; + if (isdigit(string[i])) { + if (found){ + nums=i; + } else{ + nume=i; + nums=i; + found=TRUE; + } + } else{ + if (found) break; + } + } + if (found){ + strcpy(staart,&string[nume+1]); + strcpy(kop,string); + kop[nums]=0; + *numlen=nume-nums+1; + return ((int)atoi(&(string[nums]))); + } + staart[0]=0; + strcpy(kop,string); + *numlen=0; + return (1); +} + + +static void an_stringenc(char *string, char *kop, char *staart, +unsigned short numlen, int pic) { + char numstr[10]; + unsigned short len,i; + + len=sprintf(numstr,"%d",pic); + + strcpy(string,kop); + for(i=len;i<numlen;i++){ + strcat(string,"0"); + } + strcat(string,numstr); + strcat(string,staart); +} + +/* om anim5's te kunnen lezen, moet een aantal gegevens bijgehouden worden: + * Een lijst van pointers naar delta's, in geheugen of ge'mmap'ed + * + * Mogelijk kan er ook een 'skiptab' aangelegd worden, om sneller + * sprongen te kunnen maken. + * + * Er moeten niet direct al plaatjes gegenereed worden, dit maakt de + * routines onbruikbaar om snel naar het goede plaatje te springen. + * Een routine voert dus de delta's uit, een andere routine maakt van + * voorgrondplaatje een ibuf; + */ + + +/* + een aantal functie pointers moet geinporteerd worden, zodat er niet + nog meer library's / objects meegelinkt hoeven te worden. + + Dezelfde structuur moet ook gebruikt kunnen worden voor het wegschrijven + van animaties. Hoe geef je dit aan ? + + Hoe snel kunnen 10 .dlta's gedecomprimeerd worden + (zonder omzetten naar rect). + + 1 - zoek naar 1e plaatje, animatie die aan de eisen voldoet + 2 - probeer volgende plaatje te vinden: + anim5 - decomprimeer + sequence - teller ophogen + directory - volgende entry + 3 - geen succes ? ga naar 1. + + +*/ + +/* + 1. Initialiseer routine met toegestane reeksen, en eerste naam + - series op naam (.0001) + - directories + - anim5 animaties + - TGA delta's + - iff 24bits delta's (.delta) + + 2. haal volgende (vorige ?) plaatje op. + + 3. vrijgeven +*/ + +/* selectie volgorde is: + 1 - anim5() + 2 - name + 3 - dir +*/ + + +static void free_anim_anim5(struct anim * anim) { + ListBase * animbase; + Anim5Delta * delta, * next; + + if (anim == NULL) return; + + animbase = &anim->anim5base; + delta = animbase->first; + + while (delta) { + next = delta->next; + + if (delta->type == ANIM5_MALLOC) free(delta->data); + BLI_remlink(animbase, delta); + free(delta); + + delta = next; + } + + if (anim->anim5mmap && anim->anim5len) { + MEM_freeN(anim->anim5mmap); + } + + anim->anim5mmap = NULL; + anim->anim5len = 0; + anim->anim5curdlta = 0; + anim->duration = 0; +} + +static void free_anim_avi (struct anim *anim) { + int i; + + if (anim == NULL) return; + if (anim->avi == NULL) return; + + AVI_close (anim->avi); + MEM_freeN (anim->avi); + anim->avi = NULL; + +#ifdef _WIN32 + + if (anim->pgf) { + AVIStreamGetFrameClose(anim->pgf); + anim->pgf = NULL; + } + + for (i = 0; i < anim->avistreams; i++){ + AVIStreamRelease(anim->pavi[i]); + } + anim->avistreams = 0; + + if (anim->pfileopen) { + AVIFileRelease(anim->pfile); + anim->pfileopen = 0; + AVIFileExit(); + } +#endif + + anim->duration = 0; +} + +static void free_anim_ibuf(struct anim * anim) { + if (anim == NULL) return; + + if (anim->ibuf1) IMB_freeImBuf(anim->ibuf1); + if (anim->ibuf2) IMB_freeImBuf(anim->ibuf2); + + anim->ibuf1 = anim->ibuf2 = NULL; +} + + +void IMB_free_anim(struct anim * anim) { + if (anim == NULL) { + printf("free anim, anim == NULL\n"); + return; + } + + free_anim_ibuf(anim); + free_anim_anim5(anim); + free_anim_movie(anim); + free_anim_avi(anim); + + free(anim); +} + +void IMB_close_anim(struct anim * anim) { + if (anim == 0) return; + + IMB_free_anim(anim); +} + + +struct anim * IMB_open_anim(char * name, int ib_flags) { + struct anim * anim; + + anim = (struct anim*)MEM_callocN(sizeof(struct anim), "anim struct"); + if (anim != NULL) { + strcpy(anim->name, name); + anim->ib_flags = ib_flags; + } + return(anim); +} + + +static int isavi (char *name) { + return AVI_is_avi (name); +} + +static int imb_get_anim_type(char * name) { + int type; + struct stat st; + + if (ib_stat(name,&st) == -1) return(0); + if (((st.st_mode) & S_IFMT) != S_IFREG) return(0); + + if (isavi(name)) return (ANIM_AVI); + if (ismovie(name)) return (ANIM_MOVIE); + + type = IMB_ispic(name); + if (type == ANIM) return (ANIM_ANIM5); + if (type) return(ANIM_SEQUENCE); + return(0); +} + +int IMB_isanim(char * name) { + int type= imb_get_anim_type(name); + + return (type && type!=ANIM_SEQUENCE); +} + +static void planes_to_rect(struct ImBuf * ibuf, int flags) { + if (ibuf == 0) return; + + /* dit komt regelrecht uit de amiga.c */ + + if (flags & IB_rect && ibuf->rect == 0) { + imb_addrectImBuf(ibuf); + imb_bptolong(ibuf); + IMB_flipy(ibuf); + imb_freeplanesImBuf(ibuf); + + if (ibuf->cmap){ + if ((flags & IB_cmap) == 0) { + IMB_applycmap(ibuf); + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + } + } else if (ibuf->depth == 18){ + int i,col; + unsigned int *rect; + + rect = ibuf->rect; + for(i=ibuf->x * ibuf->y ; i>0 ; i--){ + col = *rect; + col = ((col & 0x3f000) << 6) + ((col & 0xfc0) << 4) + + ((col & 0x3f) << 2); + col += (col & 0xc0c0c0) >> 6; + *rect++ = col; + } + ibuf->depth = 24; + } else if (ibuf->depth <= 8) { + /* geen colormap en geen 24 bits: zwartwit */ + uchar *rect; + int size, shift; + + if (ibuf->depth < 8){ + rect = (uchar *) ibuf->rect; + rect += 3; + shift = 8 - ibuf->depth; + for (size = ibuf->x * ibuf->y; size > 0; size --){ + rect[0] <<= shift; + rect += 4; + } + } + rect = (uchar *) ibuf->rect; + for (size = ibuf->x * ibuf->y; size > 0; size --){ + rect[1] = rect[2] = rect[3]; + rect += 4; + } + ibuf->depth = 8; + } + } +} + + +static void anim5decode(struct ImBuf * ibuf, uchar * dlta) { + uchar depth; + int skip; + int *ofspoint; + uchar **planes; + + /* samenstelling delta: + lijst met ofsets voor delta's per bitplane (ofspoint) + per kolom in delta (point) + aantal handelingen (noops) + code + bijbehorende data + ... + ... + */ + + dlta += 8; + + ofspoint = (int *)dlta; + skip = ibuf->skipx * sizeof(int *); + planes = (uchar **)ibuf->planes; + + for(depth=ibuf->depth ; depth>0 ; depth--){ + if (GET_BIG_LONG(ofspoint)){ + uchar *planestart; + uchar *point; + uchar x; + + point = dlta + GET_BIG_LONG(ofspoint); + planestart = planes[0]; + x = (ibuf->x + 7) >> 3; + + do{ + uchar noop; + + if (noop = *(point++)){ + uchar *plane; + uchar code; + + plane = planestart; + do{ + if ((code = *(point++))==0){ + uchar val; + + code = *(point++); + val = *(point++); + do { + plane[0] = val; + plane += skip; + } while(--code); + + } else if (code & 128){ + + code &= 0x7f; + do{ + plane[0] = *(point++); + plane += skip; + } while(--code); + + } else plane += code * skip; + + } while(--noop); + } + planestart++; + } while(--x); + } + ofspoint++; + planes++; + } +} + + +static void anim5xordecode(struct ImBuf * ibuf, uchar * dlta) { + uchar depth; + int skip; + int *ofspoint; + uchar **planes; + + /* samenstelling delta: + lijst met ofsets voor delta's per bitplane (ofspoint) + per kolom in delta (point) + aantal handelingen (noops) + code + bijbehorende data + ... + ... + */ + + dlta += 8; + + ofspoint = (int *)dlta; + skip = ibuf->skipx * sizeof(int *); + planes = (uchar **)ibuf->planes; + + for(depth=ibuf->depth ; depth>0 ; depth--){ + + if (GET_BIG_LONG(ofspoint)){ + uchar *planestart; + uchar *point; + uchar x; + + point = dlta + GET_BIG_LONG(ofspoint); + planestart = planes[0]; + x = (ibuf->x + 7) >> 3; + + do{ + uchar noop; + + if (noop = *(point++)){ + uchar *plane; + uchar code; + + plane = planestart; + do{ + if ((code = *(point++))==0){ + uchar val; + + code = *(point++); + val = *(point++); + do{ + plane[0] ^= val; + plane += skip; + }while(--code); + + } else if (code & 128){ + + code &= 0x7f; + do{ + plane[0] ^= *(point++); + plane += skip; + }while(--code); + + } else plane += code * skip; + + }while(--noop); + } + planestart++; + }while(--x); + } + ofspoint++; + planes++; + } +} + +static int nextanim5(struct anim * anim) { + Anim5Delta * delta; + struct ImBuf * ibuf; + + if (anim == 0) return(-1); + + delta = anim->anim5curdlta; + + if (delta == 0) return (-1); + + if (anim->anim5flags & ANIM5_SNGBUF) { + ibuf = anim->ibuf1; + if (ibuf == 0) return (0); + anim->anim5decode(ibuf, delta->data); + } else { + ibuf = anim->ibuf2; + if (ibuf == 0) return (0); + anim->anim5decode(ibuf, delta->data); + anim->ibuf2 = anim->ibuf1; + anim->ibuf1 = ibuf; + } + + anim->anim5curdlta = anim->anim5curdlta->next; + anim->curposition++; + + return(0); +} + +static int rewindanim5(struct anim * anim) { + Anim5Delta * delta; + struct ImBuf * ibuf; + + if (anim == 0) return (-1); + + free_anim_ibuf(anim); + + delta = anim->anim5base.first; + if (delta == 0) return (-1); + + ibuf = IMB_loadiffmem(delta->data, IB_planes); + if (ibuf == 0) return(-1); + + anim->ibuf1 = ibuf; + if ((anim->anim5flags & ANIM5_SNGBUF) == 0) anim->ibuf2 = IMB_dupImBuf(ibuf); + + anim->anim5curdlta = delta->next; + anim->curposition = 0; + + return(0); +} + + +static int startanim5(struct anim * anim) { + int file, buf[20], totlen; + unsigned int len; + short * mem; + ListBase * animbase; + Anim5Delta * delta; + Anhd anhd; + + /* Controles */ + + if (anim == 0) return(-1); + + file = open(anim->name,O_BINARY|O_RDONLY); + if (file < 0) return (-1); + + if (read(file, buf, 24) != 24) { + close(file); + return(-1); + } + + if ((GET_ID(buf) != FORM) || (GET_ID(buf + 2) != ANIM) + || (GET_ID(buf + 3) != FORM) || (GET_ID(buf + 5) != ILBM)){ + printf("No anim5 file %s\n",anim->name); + close(file); + return (-1); + } + + /* de hele file wordt in het geheugen gemapped */ + + totlen = BLI_filesize(file); + if (totlen && file>=0) { + lseek(file, 0L, SEEK_SET); + + mem= MEM_mallocN(totlen, "mmap"); + if (read(file, mem, totlen) != totlen) { + MEM_freeN(mem); + mem = NULL; + } + } else { + mem = NULL; + } + close (file); + + if (!mem) return (-1); + + anhd.interleave = 0; + anhd.bits = 0; + anhd.type = 5; + + anim->anim5mmap = mem; + anim->anim5len = totlen; + anim->anim5flags = 0; + anim->duration = 0; + + animbase = & anim->anim5base; + animbase->first = animbase->last = 0; + + /* eerste plaatje inlezen */ + + mem = mem + 6; + totlen -= 12; + + len = GET_BIG_LONG(mem + 2); + len = (len + 8 + 1) & ~1; + delta = NEW(Anim5Delta); + + delta->data = mem; + delta->type = ANIM5_MMAP; + + BLI_addtail(animbase, delta); + + mem += (len >> 1); + totlen -= len; + + while (totlen > 0) { + len = GET_BIG_LONG(mem + 2); + len = (len + 8 + 1) & ~1; + + switch(GET_ID(mem)){ + case FORM: + len = 12; + break; + case ANHD: + memcpy(&anhd, mem + 4, sizeof(Anhd)); + break; + case DLTA: + delta = NEW(Anim5Delta); + delta->data = mem; + delta->type = ANIM5_MMAP; + BLI_addtail(animbase, delta); + break; + } + + mem += (len >> 1); + totlen -= len; + } + + if (anhd.interleave == 1) anim->anim5flags |= ANIM5_SNGBUF; + if (BIG_SHORT(anhd.bits) & 2) anim->anim5decode = anim5xordecode; + else anim->anim5decode = anim5decode; + + /* laatste twee delta's wissen */ + + delta = animbase->last; + if (delta) { + BLI_remlink(animbase, delta); + free(delta); + } + + if ((anim->anim5flags & ANIM5_SNGBUF) == 0) { + delta = animbase->last; + if (delta) { + BLI_remlink(animbase, delta); + free(delta); + } + } + + anim->duration = BLI_countlist(animbase); + + return(rewindanim5(anim)); +} + + +static struct ImBuf * anim5_fetchibuf(struct anim * anim) { + struct ImBuf * ibuf; + + if (anim == 0) return (0); + + ibuf = IMB_dupImBuf(anim->ibuf1); + planes_to_rect(ibuf, anim->ib_flags); + + return(ibuf); +} + +static int startavi (struct anim *anim) { + + AviError avierror; +#ifdef _WIN32 + HRESULT hr; + int i, firstvideo = -1; + BYTE abFormat[1024]; + LONG l; + LPBITMAPINFOHEADER lpbi; + AVISTREAMINFO avis; +#endif + + anim->avi = MEM_callocN (sizeof(AviMovie),"animavi"); + + if (anim->avi == NULL) { + printf("Can't open avi: %s\n", anim->name); + return -1; + } + + avierror = AVI_open_movie (anim->name, anim->avi); + +#ifdef _WIN32 + if (avierror == AVI_ERROR_COMPRESSION) { + AVIFileInit(); + hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L); + if (hr == 0) { + anim->pfileopen = 1; + for (i = 0; i < MAXNUMSTREAMS; i++) { + if (AVIFileGetStream(anim->pfile, &anim->pavi[i], 0L, i) != AVIERR_OK) { + break; + } + + AVIStreamInfo(anim->pavi[i], &avis, sizeof(avis)); + if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) { + anim->pgf = AVIStreamGetFrameOpen(anim->pavi[i], NULL); + if (anim->pgf) { + firstvideo = i; + + // get stream length + anim->avi->header->TotalFrames = AVIStreamLength(anim->pavi[i]); + + // get information about images inside the stream + l = sizeof(abFormat); + AVIStreamReadFormat(anim->pavi[i], 0, &abFormat, &l); + lpbi = (LPBITMAPINFOHEADER)abFormat; + anim->avi->header->Height = lpbi->biHeight; + anim->avi->header->Width = lpbi->biWidth; + } else { + FIXCC(avis.fccHandler); + FIXCC(avis.fccType); + printf("Can't find AVI decoder for type : %4.4hs/%4.4hs\n", + (LPSTR)&avis.fccType, + (LPSTR)&avis.fccHandler); + } + } + } + + // register number of opened avistreams + anim->avistreams = i; + + // + // Couldn't get any video streams out of this file + // + if ((anim->avistreams == 0) || (firstvideo == -1)) { + avierror = AVI_ERROR_FORMAT; + } else { + avierror = AVI_ERROR_NONE; + anim->firstvideo = firstvideo; + } + } else { + AVIFileExit(); + } + } +#endif + + if (avierror != AVI_ERROR_NONE) { + AVI_print_error(avierror); + printf ("Error loading avi: %s\n", anim->name); + free_anim_avi(anim); + return -1; + } + + anim->duration = anim->avi->header->TotalFrames; + anim->params = 0; + + anim->x = anim->avi->header->Width; + anim->y = anim->avi->header->Height; + anim->interlacing = 0; + anim->orientation = 0; + anim->framesize = anim->x * anim->y * 4; + + anim->curposition = 0; + + /* printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/ + + return 0; +} + +static ImBuf * avi_fetchibuf (struct anim *anim, int position) { + ImBuf *ibuf = NULL; + int *tmp; + int y; + + if (anim == NULL) return (NULL); + +#ifdef _WIN32 + if (anim->avistreams) { + LPBITMAPINFOHEADER lpbi; + + if (anim->pgf) { + lpbi = AVIStreamGetFrame(anim->pgf, position + AVIStreamStart(anim->pavi[anim->firstvideo])); + if (lpbi) { + ibuf = IMB_ibImageFromMemory((int *) lpbi, 100, IB_rect); + } + } + } else { +#else + if (1) { +#endif + ibuf = IMB_allocImBuf (anim->x, anim->y, 24, IB_rect, 0); + + tmp = AVI_read_frame (anim->avi, AVI_FORMAT_RGB32, position, + AVI_get_stream(anim->avi, AVIST_VIDEO, 0)); + + if (tmp == NULL) { + printf ("Error reading frame from AVI"); + IMB_freeImBuf (ibuf); + return NULL; + } + + for (y=0; y < anim->y; y++) { + memcpy (&(ibuf->rect)[((anim->y-y)-1)*anim->x], &tmp[y*anim->x], + anim->x * 4); + } + + MEM_freeN (tmp); + } + + return ibuf; +} + +/* probeer volgende plaatje te lezen */ +/* Geen plaatje, probeer dan volgende animatie te openen */ +/* gelukt, haal dan eerste plaatje van animatie */ + +static struct ImBuf * anim_getnew(struct anim * anim) { + struct ImBuf *ibuf = 0; + + if (anim == NULL) return(0); + + free_anim_anim5(anim); + free_anim_movie(anim); + free_anim_avi(anim); + + if (anim->curtype != 0) return (0); + anim->curtype = imb_get_anim_type(anim->name); + + switch (anim->curtype) { + case ANIM_ANIM5: + if (startanim5(anim)) return (0); + ibuf = anim5_fetchibuf(anim); + break; + case ANIM_SEQUENCE: + ibuf = IMB_loadiffname(anim->name, anim->ib_flags); + if (ibuf) { + strcpy(anim->first, anim->name); + anim->duration = 1; + } + break; + case ANIM_MOVIE: + if (startmovie(anim)) return (0); + ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0); /* fake */ + break; + case ANIM_AVI: + if (startavi(anim)) return (0); + ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0); + break; + } + + return(ibuf); +} + + +struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { + struct ImBuf * ibuf = 0; + char head[256], tail[256]; + unsigned short digits; + int pic; + + if (anim == NULL) return(0); + + if (anim->curtype == 0) { + ibuf = anim_getnew(anim); + if (ibuf == NULL) return (0); + IMB_freeImBuf(ibuf); /* ???? */ + } + + if (position < 0) return(0); + if (position >= anim->duration) return(0); + + switch(anim->curtype) { + case ANIM_ANIM5: + if (anim->curposition > position) rewindanim5(anim); + while (anim->curposition < position) { + if (nextanim5(anim)) return (0); + } + ibuf = anim5_fetchibuf(anim); + break; + case ANIM_SEQUENCE: + pic = an_stringdec(anim->first, head, tail, &digits); + pic += position; + an_stringenc(anim->name, head, tail, digits, pic); + ibuf = IMB_loadiffname(anim->name, LI_rect); + if (ibuf) { + anim->curposition = position; + /* patch... by freeing the cmap you prevent a double apply cmap... */ + /* probably the IB_CMAP option isn't working proper + * after the abgr->rgba reconstruction + */ + IMB_freecmapImBuf(ibuf); + } + break; + case ANIM_MOVIE: + ibuf = movie_fetchibuf(anim, position); + if (ibuf) { + anim->curposition = position; + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + } + break; + case ANIM_AVI: + ibuf = avi_fetchibuf(anim, position); + if (ibuf) anim->curposition = position; + break; + } + + if (ibuf) { + if (anim->ib_flags & IB_ttob) IMB_flipy(ibuf); + sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1); + + } + return(ibuf); +} + +struct ImBuf * IMB_anim_nextpic(struct anim * anim) { + struct ImBuf * ibuf = 0; + + if (anim == 0) return(0); + + ibuf = IMB_anim_absolute(anim, anim->curposition + 1); + + return(ibuf); +} + +/***/ + +int IMB_anim_get_duration(struct anim *anim) { + return anim->duration; +} diff --git a/source/blender/imbuf/intern/antialias.c b/source/blender/imbuf/intern/antialias.c new file mode 100644 index 00000000000..de45a47a708 --- /dev/null +++ b/source/blender/imbuf/intern/antialias.c @@ -0,0 +1,471 @@ +/** + * antialias.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "imbuf.h" + +#include "BLI_blenlib.h" +#include "DNA_listBase.h" + +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" + +/* werking: + +1 - zoek een overgang in een kolom +2 - kijk wat de relatie met links en rechts is, + + Is pixel boven overgang links of rechts ervan gelijk aan bovenste kleur, + zoek dan naar beneden. + + Is pixel onder overgang links of rechts ervan gelijk aan onderste kleur, + zoek dan naar boven. + + +*/ + +/* er moet een functie * komen die aan kan geven of twee kleuren nu + * wel of niet gelijk zijn. + * Voor nu maar een define + */ + + +/* + zipfork "cc -g anti.c util.o -lgl_s -limbuf -limage -lm -o anti > /dev/console" + zipfork "anti /data/rt > /dev/console" + zipfork "anti /pics/martin/03.01.ChambFinal/0001 > /dev/console" +*/ + +static unsigned int anti_mask = 0xffffffff; +static int anti_a, anti_b, anti_g, anti_r; + +#define compare(x, y) ((x ^ y) & anti_mask) + +typedef struct Edge +{ + struct Edge * next, * prev; + short position; + int col1, col2; +}Edge; + +static void anti_free_listarray(int count, ListBase * listarray) +{ + int i; + + if (listarray == 0) return; + + for (i = 0; i < count; i++) BLI_freelistN(listarray + i); + MEM_freeN(listarray); +} + +static ListBase * scanimage(struct ImBuf * ibuf, int dir) +{ + int step, pixels, lines, nextline, x, y, col1, col2; + unsigned int * rect; + ListBase * listarray, * curlist; + Edge * edge; + int count; + + switch (dir) { + case 'h': + step = 1; nextline = ibuf->x; + pixels = ibuf->x; lines = ibuf->y; + break; + case 'v': + step = ibuf->x; nextline = 1; + pixels = ibuf->y; lines = ibuf->x; + } + + listarray = (ListBase*)MEM_callocN((lines)* sizeof(ListBase), "listarray"); + for (y = 0; y < lines; y++){ + rect = ibuf->rect; + rect += y * nextline; + curlist = listarray + y; + + col1 = rect[0]; + count = 0; + + for (x = 0; x < pixels; x++) { + col2 = rect[0]; + if (compare(col1, col2)) { + edge = NEW(Edge); + edge->position = x; + edge->col1 = col1; + edge->col2 = col2; + BLI_addtail(curlist, edge); + col1 = col2; + count++; + if (count > 100) { + printf("\n\n%s: Aborting antialias !\n", ibuf->name); + printf("To many transitions.\nIs this a natural image ?\n\n"), + anti_free_listarray(lines, listarray); + return(0); + } + } + rect += step; + } + } + + return(listarray); +} + + +static Edge * findmatch(Edge * first, Edge * edge) +{ + Edge * match = 0; + int in = 0, out = 65535; + + if (edge->prev) in = edge->prev->position; + if (edge->next) out = edge->next->position; + + while (first) { + if (first->position < edge->position) { + if (first->col1 == edge->col1) { + if (first->position >= in) match = first; + } else if (first->col2 == edge->col2) { + if (first->next == 0) match = first; + else if (first->next->position >= edge->position) match = first; + } else if (first->col2 == edge->col1) { + match = 0; /* bij zigzagjes kan deze al 'ns foutief gezet zijn */ + } + } else if (first->position == edge->position) { + if (first->col1 == edge->col1 || first->col2 == edge->col2) match = first; + } else { + if (match) break; /* er is er al een */ + + if (first->col1 == edge->col1) { + if (first->prev == 0) match = first; + else if (first->prev->position <= edge->position) match = first; + } else if (first->col2 == edge->col2) { + if (first->position <= out) match = first; + } + } + + first = first->next; + } + + return(match); +} + + +static void filterdraw(unsigned int * ldest, unsigned int * lsrce, int zero, int half, int step) +{ + uchar * src, * dst; + int count; + double weight, add; + + /* we filteren de pixels op ldest tussen in en out met pixels van lsrce + * Het gewicht loopt ondertussen van 0 naar 1 + */ + + + count = half - zero; + if (count < 0) count = -count; + if (count <= 1) return; + + if (zero < half) { + src = (uchar *) (lsrce + (step * zero)); + dst = (uchar *) (ldest + (step * zero)); + } else { + zero--; + src = (uchar *) (lsrce + (step * zero)); + dst = (uchar *) (ldest + (step * zero)); + step = -step; + } + + step = 4 * step; + + dst += step * (count >> 1); + src += step * (count >> 1); + + count = (count + 1) >> 1; + add = 0.5 / count; + weight = 0.5 * add; + + /* dit moet natuurlijk gamma gecorrigeerd */ + + for(; count > 0; count --) { + if (anti_a) dst[0] += weight * (src[0] - dst[0]); + if (anti_b) dst[1] += weight * (src[1] - dst[1]); + if (anti_g) dst[2] += weight * (src[2] - dst[2]); + if (anti_r) dst[3] += weight * (src[3] - dst[3]); + dst += step; + src += step; + weight += add; + } +} + +static void filterimage(struct ImBuf * ibuf, struct ImBuf * cbuf, ListBase * listarray, int dir) +{ + int step, pixels, lines, nextline, y, pos, drawboth; + unsigned int * irect, * crect; + Edge * left, * middle, * right, temp, * any; + + switch (dir) { + case 'h': + step = 1; nextline = ibuf->x; + pixels = ibuf->x; lines = ibuf->y; + break; + case 'v': + step = ibuf->x; nextline = 1; + pixels = ibuf->y; lines = ibuf->x; + } + + for (y = 1; y < lines - 1; y++){ + irect = ibuf->rect; + irect += y * nextline; + crect = cbuf->rect; + crect += y * nextline; + + middle = listarray[y].first; + while (middle) { + left = findmatch(listarray[y - 1].first, middle); + right = findmatch(listarray[y + 1].first, middle); + drawboth = FALSE; + + if (left == 0 || right == 0) { + /* rand */ + any = left; + if (right) any = right; + if (any) { + /* spiegelen */ + pos = 2 * middle->position - any->position; + + if (any->position < middle->position) { + if (pos > pixels - 1) pos = pixels - 1; + if (middle->next) { + if (pos > middle->next->position) pos = middle->next->position; + } +/* if (any->next) { + if (pos > any->next->position) pos = any->next->position; + } +*/ } else { + if (pos < 0) pos = 0; + if (middle->prev) { + if (pos < middle->prev->position) pos = middle->prev->position; + } +/* if (any->prev) { + if (pos < any->prev->position) pos = any->prev->position; + } +*/ } + temp.position = pos; + if (left) right = &temp; + else left = &temp; + drawboth = TRUE; + } + } else if (left->position == middle->position || right->position == middle->position) { + /* recht stuk */ + /* klein hoekje, met een van de twee op afstand 2 (ander is toch op afstand 0) ? */ + + if (abs(left->position - right->position) == 2) drawboth = TRUE; + } else if (left->position < middle->position && right->position > middle->position){ + /* trap 1 */ + drawboth = TRUE; + } else if (left->position > middle->position && right->position < middle->position){ + /* trap 2 */ + drawboth = TRUE; + } else { + /* piek */ + drawboth = TRUE; + } + + if (drawboth) { + filterdraw(irect, crect - nextline, left->position, middle->position, step); + filterdraw(irect, crect + nextline, right->position, middle->position, step); + } + + middle = middle->next; + } + } +} + + +void IMB_antialias(struct ImBuf * ibuf) +{ + struct ImBuf * cbuf; + ListBase * listarray; + + if (ibuf == 0) return; + cbuf = IMB_dupImBuf(ibuf); + + anti_a = (anti_mask >> 24) & 0xff; + anti_b = (anti_mask >> 16) & 0xff; + anti_g = (anti_mask >> 8) & 0xff; + anti_r = (anti_mask >> 0) & 0xff; + + listarray = scanimage(cbuf, 'h'); + if (listarray) { + filterimage(ibuf, cbuf, listarray, 'h'); + anti_free_listarray(ibuf->y, listarray); + + listarray = scanimage(cbuf, 'v'); + if (listarray) { + filterimage(ibuf, cbuf, listarray, 'v'); + anti_free_listarray(ibuf->x, listarray); + } + } + + IMB_freeImBuf(cbuf); +} + + +/* intelligente scaling */ + +static void _intel_scale(struct ImBuf * ibuf, ListBase * listarray, int dir) +{ + int step, lines, nextline, x, y, col; + unsigned int * irect, * trect; + int start, end; + Edge * left, * right; + struct ImBuf * tbuf; + + switch (dir) { + case 'h': + step = 1; nextline = ibuf->x; + lines = ibuf->y; + tbuf = IMB_double_fast_y(ibuf); + break; + case 'v': + step = 2 * ibuf->x; nextline = 1; + lines = ibuf->x; + tbuf = IMB_double_fast_x(ibuf); + break; + default: + return; + } + + imb_freerectImBuf(ibuf); + ibuf->rect = tbuf->rect; + ibuf->mall |= IB_rect; + + + ibuf->x = tbuf->x; + ibuf->y = tbuf->y; + tbuf->rect = 0; + IMB_freeImBuf(tbuf); + + for (y = 0; y < lines - 2; y++){ + irect = ibuf->rect; + irect += ((2 * y) + 1) * nextline; + + left = listarray[y].first; + while (left) { + right = findmatch(listarray[y + 1].first, left); + if (right) { + if (left->col2 == right->col2) { + if (left->next && right->next) { + if (left->next->position >= right->position) { + start = ((left->position + right->position) >> 1); + end = ((left->next->position + right->next->position) >> 1); + col = left->col2; + trect = irect + (start * step); + for (x = start; x < end; x++) { + *trect = col; + trect += step; + } + } + } + } + + if (left->col1 == right->col1) { + if (left->prev && right->prev) { + if (left->prev->position <= right->position) { + end = ((left->position + right->position) >> 1); + start = ((left->prev->position + right->prev->position) >> 1); + col = left->col1; + trect = irect + (start * step); + for (x = start; x < end; x++) { + *trect = col; + trect += step; + } + } + } + } + + } + left = left->next; + } + } +} + + +void IMB_clever_double(struct ImBuf * ibuf) +{ + ListBase * listarray, * curlist; + Edge * new; + int size; + int i; + + if (ibuf == 0) return; + + size = ibuf->x; + listarray = scanimage(ibuf, 'v'); + if (listarray) { + for (i = 0; i < size; i++) { + curlist = listarray + i; + new = (Edge*)MEM_callocN(sizeof(Edge),"Edge"); + new->col2 = ibuf->rect[i]; /* bovenste pixel */ + new->col1 = new->col2 - 1; + BLI_addhead(curlist, new); + new = (Edge*)MEM_callocN(sizeof(Edge),"Edge"); + new->position = ibuf->y - 1; + new->col1 = ibuf->rect[i + ((ibuf->y -1) * ibuf->x)]; /* onderste pixel */ + new->col2 = new->col1 - 1; + BLI_addtail(curlist, new); + } + _intel_scale(ibuf, listarray, 'v'); + anti_free_listarray(size, listarray); + + size = ibuf->y; + listarray = scanimage(ibuf, 'h'); + if (listarray) { + for (i = 0; i < size; i++) { + curlist = listarray + i; + new = (Edge*)MEM_callocN(sizeof(Edge),"Edge"); + new->col2 = ibuf->rect[i * ibuf->x]; /* linkse pixel */ + new->col1 = new->col2 - 1; + BLI_addhead(curlist, new); + new = (Edge*)MEM_callocN(sizeof(Edge),"Edge"); + new->position = ibuf->x - 1; + new->col1 = ibuf->rect[((i + 1) * ibuf->x) - 1]; /* rechtse pixel */ + new->col2 = new->col1 - 1; + BLI_addtail(curlist, new); + } + _intel_scale(ibuf, listarray, 'h'); + anti_free_listarray(size, listarray); + } + } +} diff --git a/source/blender/imbuf/intern/bitplanes.c b/source/blender/imbuf/intern/bitplanes.c new file mode 100644 index 00000000000..0f1c4bf238c --- /dev/null +++ b/source/blender/imbuf/intern/bitplanes.c @@ -0,0 +1,359 @@ +/** + * bitplanes.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "imbuf.h" +#include "BLI_blenlib.h" + +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_bitplanes.h" + + +unsigned int **imb_copyplanelist(struct ImBuf *ibuf) +{ + int nobp,i; + unsigned int **listn,**listo; + + nobp=ibuf->depth; + listn= malloc(nobp*sizeof(int *)); /* kopie van bitmap maken */ + if (listn==0) return (0); + + listo=ibuf->planes; + for (i=nobp;i>0;i--){ + *(listn++) = *(listo++); + } + listn -= nobp; + + return (listn); +} + +static void bptolscanl(unsigned int *buf, int size, unsigned int **list, int nobp, int offset) +{ + /* zet bitplanes om in een buffer met ints + door 4 deelbare hoeveelheid bitplanes, + breedte bitplanes op ints afgrond */ + + list += nobp; + + for (;nobp>0;) + { + int todo,i; + register int bp1, bp2, bp3, data; + register unsigned int *point; + int bp4, loffset; + /*register unsigned int bp1, bp2, bp3, bp4;*/ + + todo = 0; + point = buf; + loffset = offset; + + if (nobp & 1){ + list -= 1; + nobp -= 1; + for(i=size;i>0;i--) + { + if (todo==0) + { + bp1 = BIG_LONG((list[0])[loffset]); + loffset++; + todo=32; + } + + data = *point; + data<<=1; + + if (bp1<0) data+=1; + bp1<<=1; + + /* data += (bp1 >> 31); + bp1 <<= 1; + */ + *(point++)=data; + todo--; + } + } else if (nobp & 2){ + list -= 2; + nobp -= 2; + for(i=size;i>0;i--) + { + if (todo==0) + { + bp1 = BIG_LONG((list[0])[loffset]); + bp2 = BIG_LONG((list[1])[loffset]); + loffset++; + todo=32; + } + + data = *point; + data<<=2; + + if (bp1<0) data+=1; + bp1<<=1; + if (bp2<0) data+=2; + bp2<<=1; + + /* data += (bp1 >> 31) + ((bp2 & 0x80000000) >> 30); + bp1 <<= 1; bp2 <<= 1; + */ + *(point++)=data; + todo--; + } + } else{ + list -= 4; + nobp -= 4; + for(i=size;i>0;i--) + { + if (todo==0) { + bp1 = BIG_LONG((list[0])[loffset]); + bp2 = BIG_LONG((list[1])[loffset]); + bp3 = BIG_LONG((list[2])[loffset]); + bp4 = BIG_LONG((list[3])[loffset]); + loffset++; + todo=32; + } + + data = *point; + data<<=4; + + if (bp1<0) data+=1; + bp1<<=1; + if (bp2<0) data+=2; + bp2<<=1; + if (bp3<0) data+=4; + bp3<<=1; + if (bp4<0) data+=8; + bp4<<=1; + + /* data += (bp1 >> 31) \ + + ((bp2 & 0x80000000) >> 30) \ + + ((bp3 & 0x80000000) >> 29) \ + + ((bp4 & 0x80000000) >> 28); + + bp1 <<= 1; bp2 <<= 1; + bp3 <<= 1; bp4 <<= 1; + */ + + *(point++)=data; + todo--; + } + } + } +} + + +void imb_bptolong(struct ImBuf *ibuf) +{ + int nobp,i,x; + unsigned int *rect,offset; + + /* eerst alle ints wissen */ + + if (ibuf == 0) return; + if (ibuf->planes == 0) return; + if (ibuf->rect == 0) imb_addrectImBuf(ibuf); + + nobp=ibuf->depth; + if (nobp != 32){ + if (nobp == 24) IMB_rectoptot(ibuf, 0, IMB_rectfill, 0xff000000); /* alpha zetten */ + else IMB_rectoptot(ibuf, 0, IMB_rectfill, 0); + } + + rect= ibuf->rect; + x= ibuf->x; + offset=0; + + for (i= ibuf->y; i>0; i--){ + bptolscanl(rect, x, ibuf->planes, nobp, offset); + rect += x; + offset += ibuf->skipx; + } +} + + +static void ltobpscanl(unsigned int *rect, int x, unsigned int **list, int nobp, int offset) +{ + /* zet een buffer met ints, om in bitplanes. Opgepast, buffer + wordt vernietigd !*/ + + if (nobp != 32) + { + int *rect2; + int todo,j; + + rect2 = (int*)rect; + + todo = 32-nobp; + for (j = x;j>0;j--){ + *(rect2++) <<= todo; + } + } + + list += nobp; + for (;nobp>0;){ + register int bp1=0, bp2=0, bp3=0, data; + register unsigned int *point; + int i,todo; + int bp4=0,loffset; + + point = rect; + todo=32; + loffset=offset; + + if (nobp & 1){ + list -= 1; + nobp -= 1; + + for(i=x;i>0;i--){ + data = *point; + + bp1 <<= 1; + if (data<0) bp1 += 1; + data <<= 1; + + *(point++) = data; + + todo--; + if (todo == 0){ + (list[0])[loffset] = bp1; + loffset++; + todo=32; + } + } + if (todo != 32) + { + bp1 <<= todo; + (list[0])[loffset] = bp1; + } + } else if (nobp & 2){ + list -= 2; + nobp -= 2; + for(i=x;i>0;i--){ + data = *point; + + bp2 <<= 1; + if (data<0) bp2 += 1; + data <<= 1; + bp1 <<= 1; + if (data<0) bp1 += 1; + data <<= 1; + + *(point++) = data; + + todo--; + if (todo == 0){ + (list[0])[loffset] = bp1; + (list[1])[loffset] = bp2; + loffset++; + todo=32; + } + } + if (todo != 32){ + bp1 <<= todo; + bp2 <<= todo; + (list[0])[loffset] = bp1; + (list[1])[loffset] = bp2; + } + } else{ + list -= 4; + nobp -= 4; + for(i=x;i>0;i--){ + data = *point; + + bp4 <<= 1; + if (data<0) bp4 += 1; + data <<= 1; + bp3 <<= 1; + if (data<0) bp3 += 1; + data <<= 1; + bp2 <<= 1; + if (data<0) bp2 += 1; + data <<= 1; + bp1 <<= 1; + if (data<0) bp1 += 1; + data <<= 1; + + *(point++) = data; + + todo--; + if (todo == 0){ + (list[0])[loffset] = bp1; + (list[1])[loffset] = bp2; + (list[2])[loffset] = bp3; + (list[3])[loffset] = bp4; + loffset++; + todo=32; + } + } + if (todo != 32){ + bp1 <<= todo; + bp2 <<= todo; + bp3 <<= todo; + bp4 <<= todo; + (list[0])[loffset] = bp1; + (list[1])[loffset] = bp2; + (list[2])[loffset] = bp3; + (list[3])[loffset] = bp4; + } + } + } +} + + +void imb_longtobp(struct ImBuf *ibuf) +{ + /* zet een buffer met ints, om in bitplanes. Opgepast, buffer + wordt vernietigd !*/ + + int nobp,i,x; + unsigned int *rect,offset,*buf; + ; + + nobp = ibuf->depth; + rect=ibuf->rect; + x=ibuf->x; + offset=0; + if ((buf=malloc(x*sizeof(int)))==0) return; + + for (i=ibuf->y;i>0;i--){ + memcpy(buf, rect, x*sizeof(int)); + rect +=x ; + ltobpscanl(buf, x, ibuf->planes, nobp, offset); + offset += ibuf->skipx; + } + free(buf); +} diff --git a/source/blender/imbuf/intern/bmp_decode.c b/source/blender/imbuf/intern/bmp_decode.c new file mode 100644 index 00000000000..d8b38f367e0 --- /dev/null +++ b/source/blender/imbuf/intern/bmp_decode.c @@ -0,0 +1,191 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_cmap.h" +#include "IMB_bmp.h" + + +// some code copied from article on microsoft.com, copied +// here for enhanced BMP support in the future +// http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0197/mfcp1/mfcp1.htm&nav=/msj/0197/newnav.htm + +/* +LPBYTE CDib::GetBits() + { + return (LPBYTE)m_pbmih + // start of bitmap + + m_pbmih->biSize + // size of header + + GetNumPaletteColors() // (num colors * + *sizeof(RGBQUAD); // size each entry) + } + +UINT CDib::GetNumPaletteColors() + { + UINT nColors=m_pbmih->biClrUsed; + if (nColors==0 && m_pbmih->biBitCount<=8) + nColors = 1<<m_pbmih->biBitCount; + return nColors; + } + +*/ + +typedef struct BMPINFOHEADER{ + unsigned int biSize; + int biWidth; + int biHeight; + unsigned short biPlanes; + unsigned short biBitCount; + unsigned int biCompression; + unsigned int biSizeImage; + int biXPelsPerMeter; + int biYPelsPerMeter; + unsigned int biClrUsed; + unsigned int biClrImportant; +} BMPINFOHEADER; + +#define BMP_FILEHEADER_SIZE 14 + +static int checkbmp(unsigned char *mem) +{ + int ret_val = 0; + BMPINFOHEADER bmi; + unsigned int u; + + if (mem) { + if ((mem[0] == 'B') && (mem[1] == 'M')) { + // skip fileheader + mem += BMP_FILEHEADER_SIZE; + } + + // for systems where an int needs to be 4 bytes aligned + memcpy(&bmi, mem, sizeof(bmi)); + + u = LITTLE_LONG(bmi.biSize); + // we only support uncompressed 24 or 32 bits images for now + if (u >= sizeof(BMPINFOHEADER)) { + if ((bmi.biCompression == 0) && (bmi.biClrUsed == 0)) { + u = LITTLE_SHORT(bmi.biBitCount); + if (u >= 16) { + ret_val = 1; + } + } + } + } + + return(ret_val); +} + +int imb_is_a_bmp(void *buf) { + + return checkbmp(buf); +} + +struct ImBuf *imb_bmp_decode(unsigned char *mem, int size, int flags) +{ + struct ImBuf *ibuf = 0; + BMPINFOHEADER bmi; + int x, y, depth, skip, i; + unsigned char *bmp, *rect; + unsigned short col; + + if (checkbmp(mem) == 0) return(0); + + if ((mem[0] == 'B') && (mem[1] == 'M')) { + // skip fileheader + mem += BMP_FILEHEADER_SIZE; + } + + // for systems where an int needs to be 4 bytes aligned + memcpy(&bmi, mem, sizeof(bmi)); + + skip = LITTLE_LONG(bmi.biSize); + x = LITTLE_LONG(bmi.biWidth); + y = LITTLE_LONG(bmi.biHeight); + depth = LITTLE_SHORT(bmi.biBitCount); + + // printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y, depth, bmi.biBitCount); + if (flags & IB_test) { + ibuf = IMB_allocImBuf(x, y, depth, 0, 0); + } else { + ibuf = IMB_allocImBuf(x, y, depth, IB_rect, 0); + bmp = mem + skip; + rect = (unsigned char *) ibuf->rect; + + if (depth == 16) { + for (i = x * y; i > 0; i--) { + col = bmp[0] + (bmp[1] << 8); + rect[0] = ((col >> 10) & 0x1f) << 3; + rect[1] = ((col >> 5) & 0x1f) << 3; + rect[2] = ((col >> 0) & 0x1f) << 3; + + rect[3] = 255; + rect += 4; bmp += 2; + } + + } else if (depth == 24) { + for (i = x * y; i > 0; i--) { + rect[0] = bmp[2]; + rect[1] = bmp[1]; + rect[2] = bmp[0]; + + rect[3] = 255; + rect += 4; bmp += 3; + } + } else if (depth == 32) { + for (i = x * y; i > 0; i--) { + rect[0] = bmp[0]; + rect[1] = bmp[1]; + rect[2] = bmp[2]; + rect[3] = bmp[3]; + rect += 4; bmp += 4; + } + } + } + + if (ibuf) { + ibuf->ftype = BMP; + } + + return(ibuf); +} + diff --git a/source/blender/imbuf/intern/cmap.c b/source/blender/imbuf/intern/cmap.c new file mode 100644 index 00000000000..300c3049dea --- /dev/null +++ b/source/blender/imbuf/intern/cmap.c @@ -0,0 +1,589 @@ +/** + * cmap.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <ctype.h> +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_cmap.h" + +static short *lastcube = 0; +static uchar *lastcoltab = 0; +static short lastmaxcol; +static short lastmincol; +static short lastcbits; +short alpha_col0 = FALSE; + + +/* + * er zit nog ergens een bug/inconsequentie in het programma. Als je een plaatje om wilt zetten + * naar een colormap met 1 bit resolutie krijg je een zwart plaatje. Zowieso alles met minder + * dan 4 bits is te donker. + */ + +void IMB_freeImBufdata(void) +{ + if (lastcube) free(lastcube); + lastcube= 0; + if (lastcoltab) free(lastcoltab); + lastcoltab= 0; +} + + +int IMB_alpha_to_col0(int new) +{ + int old; + + old = alpha_col0; + alpha_col0 = new; + return (old); +} + + +void imb_losecmapbits(struct ImBuf *ibuf, unsigned int *coltab) +{ + int i,bits; + unsigned int col, and1, and2, *rect; + + if (ibuf == 0) return; + if (ibuf->rect == 0) return; + if (ibuf->cbits == 0) return; + if (ibuf->cbits >= 8) return; + + /* + bij cbits = 5: + and1 = 11100000; + bij cbits = 6: + and1 = 11000000; + */ + + bits = ibuf->cbits; + and1 = ((1 << (8-bits)) - 1) & 0xff; + and1 |= (and1 << 24) + (and1 << 16) + (and1 << 8); + and2 = ~and1; + and1 <<= bits; + + rect = ibuf->rect; + for (i = ibuf->x * ibuf->y ; i > 0; i--) { + col = rect[0]; + *rect++ = col - ((col & and1) >> bits); + } + + if (coltab){ + for (i = 0 ; i < ibuf->maxcol ; i++) { + col = coltab[i]; + coltab[i] = (col - ((col & and1) >> bits)) & and2; + } + } +} + + +static void addcmapbits(struct ImBuf *ibuf) +/* struct ImBuf *ibuf; */ +{ + int i,bits; + int div,mul; + uchar * cmap; + + if (ibuf == 0) return; + if (ibuf->cmap == 0) return; + if (ibuf->cbits == 0) return; + if (ibuf->cbits >= 8) return; + + bits = ibuf->cbits; + + /* bits = 4 -> div = 0xf0 + * bits = 5 -> div = 0xf8 + */ + + div = ((1 << bits) - 1) << (8 - bits); + mul = 0xffff / div; + + if (ibuf->cmap){ + cmap = (uchar *) ibuf->cmap; + for (i = 0 ; i < ibuf->maxcol ; i++){ + cmap[1] = (mul * cmap[1]) >> 8; + cmap[2] = (mul * cmap[2]) >> 8; + cmap[3] = (mul * cmap[3]) >> 8; + cmap += 4; + } + } +} + + +static short addplanetocube(short *cube, short *plane, int minx, int miny, int sizep, int addcx, int addcy, int sizec, int col) +{ + short done = FALSE; + int x, numx, numy, skipc, skipp, temp; + + /* eerst maar eens clippen */ + + numx = numy = sizep; + + temp = minx + sizep - 1; + if (temp > sizec) numx -= temp - sizec; + + temp = miny + sizep - 1; + if (temp > sizec) numy -= temp - sizec; + + if (minx < 0){ + plane -= minx; + cube -= minx * addcx; + numx += minx; + } + + if (miny < 0){ + plane -= miny * sizep; + cube -= miny * addcy; + numy += miny; + } + + skipc = addcy - (numx * addcx); + skipp = sizep - numx; + + for (; numy > 0 ; numy--){ + for (x = numx ; x > 0; x--) { + + if (plane[0] < cube[1]) { + + cube[0] = col; + cube[1] = plane[0]; + done = TRUE; + } + plane ++; + cube += addcx; + } + plane += skipp; + cube += skipc; + } + + return (done); +} + + + +short *imb_coldeltatab(unsigned char *coltab, short mincol, short maxcol, short cbits) +{ + short max, *quadr, *_quadr, *_cube, *cube, *_plane, done, nocol; + unsigned int addcb, addcg, addcr, sizep; + uchar *_colp, *colp, *col; + int i, j, k, addcube; + int r, g, b; + + max = (1 << cbits) - 1; + nocol = maxcol - mincol; + coltab += 4 * mincol; + + /* kleuren terugbrengen tot juiste hoeveelheid bits */ + + { + unsigned int * lctab, and; + + lctab = (unsigned int *) coltab; + and = max << (8 - cbits); + and = and + (and << 8) + (and << 16) + (and << 24); + for (i=nocol-1 ; i >= 0 ; i--) lctab[i] = (lctab[i] & and) >> (8 - cbits); + } + + /* zijn deze gegevens hetzelfde als de vorige ? */ + + if (lastcube){ + if (mincol == lastmincol && maxcol == lastmaxcol && cbits == lastcbits){ + if (lastcoltab){ + if (memcmp(lastcoltab, coltab, 4 * nocol) == 0) return(lastcube); + } + } + } + if (lastcube) free(lastcube); + if (lastcoltab) free(lastcoltab); + + lastcube = 0; + lastcoltab = 0; + _cube = malloc(2 * (1 << (3 * cbits)) * sizeof(short)); + _plane = malloc((2 * max + 1) * (2 * max + 1) * sizeof(short)); + _quadr = malloc((2 * max + 1) * sizeof(short)); + _colp = malloc(6 * nocol); + + if (_cube == 0 || _plane == 0 || _quadr == 0 || _colp == 0){ + if (_cube) free(_cube); + if (_plane) free(_plane); + if (_quadr) free(_quadr); + if (_colp) free(_colp); + return(0); + } + + lastcoltab = malloc(4 * nocol); + if (lastcoltab) memcpy(lastcoltab, coltab, 4 * nocol); + lastcube = _cube; + lastmincol = mincol; + lastmaxcol = maxcol; + lastcbits = cbits; + + /* cube initialiseren */ + + cube = _cube; + for (i = (1 << (3 * cbits)); i > 0 ; i--){ + cube[0] = 0; + cube[1] = 32767; + cube += 2; + } + + /* error look up table aan maken */ + + { + unsigned int delta; + + quadr = _quadr + max + 1; + quadr[0] = 0; + delta = 3; + for (i = 1 ; i <= max ; i++){ + quadr[i] = quadr[-i] = delta; + delta += i + 3; + } + } + + /* colorplane initialiseren */ + + for (i = 6 * nocol - 1; i >= 0; i--) _colp[i] = 1; + + addcr = 2; + addcg = (addcr << cbits); + addcb = (addcg << cbits); + + /* eerste ronde invullen */ + + { + unsigned int ofs; + + col = coltab; + cube = _cube; + + for (i = 0 ; i < nocol ; i++){ + ofs = (col[3] * addcr) + (col[2] * addcg) + (col[1] * addcb); + /* is deze kleur al ingevuld -> dan overslaan */ + if (cube[ofs + 1]) cube[ofs] = i + mincol; + cube[ofs + 1] = 0; + col += 4; + } + } + + for (i = 1; i <= max ; i++){ + colp = _colp; + col = coltab; + done = FALSE; + sizep = 2*i +1; + + /* plane initialiseren */ + { + unsigned int delta; + short *plane; + + plane = _plane; + for (j = -i ; j <= i; j++){ + delta = quadr[i] + quadr[j]; + for (k = -i; k <= i; k++){ + *plane++ = delta + quadr[k]; + } + } + } + + for (j = mincol; j < maxcol; j++){ + b = col[1] - i; + g = col[2] - i; + r = col[3] - i; + + addcube= (addcr * r) + (addcg * g) + (addcb * b); + /* PRINT4(d, d, d, d, addcube, r, g, b); */ + /* if(addcube >= 2 * (1 << (3 * cbits))) { */ + /* printf("maxerror: %d %d\n", addcube, 2 * (1 << (3 * cbits))); */ + /* add_cube= 2 * (1 << (3 * cbits)) -1; */ + /* } */ + cube = _cube + addcube; + + if (colp[0]){ + if (b < 0) colp[0] = 0; + else done |= colp[0] = addplanetocube(cube, _plane, r, g, sizep, addcr, addcg, max, j); + } + if (colp[1]){ + if (g < 0) colp[1] = 0; + else done |= colp[1] = addplanetocube(cube, _plane, r, b, sizep, addcr, addcb, max, j); + } + if (colp[2]){ + if (r < 0) colp[2] = 0; + else done |= colp[2] = addplanetocube(cube, _plane, b, g, sizep, addcb, addcg, max, j); + } + if (colp[3]){ + if ((b + sizep - 1) > max) colp[3] = 0; + else done |= colp[3] = addplanetocube(cube + (sizep -1) * addcb, _plane, r, g, sizep, addcr, + addcg, max, j); + } + if (colp[4]){ + if ((g + sizep - 1) > max) colp[4] = 0; + else done |= colp[4] = addplanetocube(cube + (sizep -1) * addcg, _plane, r, b, sizep, addcr, + addcb, max, j); + } + if (colp[5]){ + if ((r + sizep - 1) > max) colp[5] = 0; + else done |= colp[5] = addplanetocube(cube + (sizep -1) * addcr, _plane, b, g, sizep, addcb, + addcg, max, j); + } + + colp += 6; + col += 4; + } + if (done == 0) break; + } + + free(_quadr); + free(_plane); + free(_colp); + return(_cube); +} + + +static void convcmap(struct ImBuf* ibuf, short *deltab, short cbits) +/* struct ImBuf* ibuf; */ +/* short *deltab,cbits; */ +{ + unsigned int *rect; + short x,y; + unsigned int col; + unsigned int bbits,gbits,rbits; + unsigned int bmask,gmask,rmask; + + bbits = 24 - 3 * cbits - 1; + gbits = 16 - 2 * cbits - 1; + rbits = 8 - cbits - 1; + + rmask = ((1 << cbits) - 1) << (8 - cbits); + gmask = rmask << 8; + bmask = gmask << 8; + + rect =(unsigned int *)ibuf->rect; + + for(y=ibuf->y;y>0;y--){ + for(x=ibuf->x;x>0;x--){ + col = *rect; + col = ((col & bmask) >> bbits) + ((col & gmask) >> gbits) + ((col & rmask) >> rbits); + *rect++ = deltab[col]; + } + } +} + +short IMB_converttocmap(struct ImBuf *ibuf) +{ + unsigned int *coltab; + short *deltab=0, cbits; + int i; + int mincol, mask; + struct ImBuf * abuf = 0; + unsigned int * rect, * arect; + + cbits = 5; + if (ibuf->cmap == 0) return(0); + + if ((ibuf->cbits > 0) && (ibuf->cbits <8)) cbits = ibuf->cbits; + + coltab = calloc(ibuf->maxcol, sizeof(unsigned int)); + if (coltab == 0) return(0); + memcpy(coltab, ibuf->cmap, ibuf->maxcol * sizeof(unsigned int)); + + mincol = ibuf->mincol; + if (alpha_col0) { + if (mincol == 0) mincol = 1; + abuf = IMB_dupImBuf(ibuf); + } + + imb_losecmapbits(ibuf, coltab); + deltab = imb_coldeltatab((uchar *) coltab, mincol ,ibuf->maxcol, cbits); + + if (deltab == 0) { + free(coltab); + if (abuf) IMB_freeImBuf(abuf); + return(0); + } + + + IMB_dit0(ibuf,1,cbits); + IMB_dit0(ibuf,2,cbits); + IMB_dit0(ibuf,3,cbits); + convcmap(ibuf, deltab, cbits); + + if (abuf) { + /* alpha omzetten naar kleur 0 */ + rect = ibuf->rect; + arect = abuf->rect; + + if (alpha_col0 == 1) mask = 0xff000000; /* alpha == 0 -> 0 */ + if (alpha_col0 == 2) mask = 0x80000000; /* alpha < 128 -> 0 */ + + for (i = ibuf->x * ibuf->y; i > 0; i--) { + if ((*arect++ & mask) == 0) rect[0] = 0; + rect++; + } + + IMB_freeImBuf(abuf); + } + + free(coltab); + + return (TRUE); +} + + +void imb_makecolarray(struct ImBuf *ibuf, unsigned char *mem, short nocols) +/* struct ImBuf *ibuf; */ +/* uchar *mem; */ +/* short nocols; */ +{ + short i,bits = 0; + uchar *cmap; + + /* wat is hier de theorie achter */ + + nocols = ibuf->maxcol; + + if (ibuf->cmap){ + cmap = (uchar *) ibuf->cmap; + for (i = 0; i < nocols; i++){ + cmap[3] = mem[0]; + cmap[2] = mem[1]; + cmap[1] = mem[2]; + cmap[0] = 0; + + bits |= mem[0] | mem[1] | mem[2]; + mem += 3; + cmap += 4; + } + + /* patch voor AdPro II */ + if (IS_ham(ibuf)){ + i = ibuf->depth - 2; + bits = ((1 << i) - 1) << (8 - i); + for (i=0 ; i<nocols ; i++) ibuf->cmap[i] &= (bits << 24) + (bits << 16) + (bits << 8) + bits; + } + + if ((bits & 0x1f) == 0){ + ibuf->cbits = 3; + } else if ((bits & 0x0f) == 0){ + ibuf->cbits = 4; + } else if ((bits & 0x07) == 0){ + ibuf->cbits = 5; + } else if ((bits & 0x03) == 0){ + ibuf->cbits = 6; + } else ibuf->cbits = 8; + + addcmapbits(ibuf); + + if (IS_hbrite(ibuf)){ + for (i=31;i>=0;i--){ + ibuf->cmap[i+32] = (ibuf->cmap[i] & 0xfefefefe) >> 1; + } + } + + if (IS_amiga(ibuf)){ + cmap = (uchar * ) (ibuf->cmap + 1); + for (i = 1; i < nocols; i++){ + cmap[0] = 0xff; + cmap += 4; + } + } + } +} + +/* temporal... rects now are rgba, cmaps are abgr */ +#define SWITCH_INT(a) {char s_i, *p_i; p_i= (char *)&(a); s_i= p_i[0]; p_i[0]= p_i[3]; p_i[3]= s_i; s_i= p_i[1]; p_i[1]= p_i[2]; p_i[2]= s_i; } + +void IMB_applycmap(struct ImBuf *ibuf) +/* struct ImBuf *ibuf; */ +{ + unsigned int *rect, *cmap; + int x, y, i, col, code; + int *mask = 0; + + if (ibuf == 0) return; + if (ibuf->rect == 0 || ibuf->cmap == 0) return; + + rect = ibuf->rect; + cmap = ibuf->cmap; + + if (IS_ham(ibuf)){ + + /* masker genereren maximaal (8 + 2) bits */ + mask = malloc(1024 * 2 * sizeof(int)); + + x = 1 << (ibuf->depth - 2); + y = 65535 / (x - 1); + + for (i = 0; i < x; i++){ + mask[i] = 0; + mask[i + x] = 0x00ffff; + mask[i + x + x] = 0xffff00; + mask[i + x + x + x] = 0xff00ff; + + col = (y * i) >> 8; + + mask[i + 1024] = 0xff000000 | ibuf->cmap[i]; + mask[i + x + 1024] = 0xff000000 | col << 16; + mask[i + x + x + 1024] = 0xff000000 | col; + mask[i + x + x + x + 1024] = 0xff000000 | col << 8; + } + + /* alleen kleur 0 transparant */ + mask[0+1024] =ibuf->cmap[0]; + + for (y = ibuf->y ; y>0 ; y--){ + col = cmap[0]; + for (x=ibuf->x ; x>0 ; x--){ + code = *rect; + *rect++ = col = (col & mask[code]) | mask[code + 1024]; + } + } + free(mask); + } else { + + for(i = ibuf->x * ibuf->y; i>0; i--){ + col = *rect; + if (col >= 0 && col < ibuf->maxcol) *rect = cmap[col]; + rect++; + + /* *(rect++) = cmap[*rect]; */ + } + } +} + diff --git a/source/blender/imbuf/intern/cspace.c b/source/blender/imbuf/intern/cspace.c new file mode 100644 index 00000000000..5cd2da5a998 --- /dev/null +++ b/source/blender/imbuf/intern/cspace.c @@ -0,0 +1,177 @@ +/** + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" + +/************************************************************************/ +/* COLORSPACE */ +/************************************************************************/ + +static void fillmattab(double val, unsigned short *mattab) +{ + int tot,ival; + int i; + + val *= (1 << 22); + ival = val; + tot = 32767; /* een half */ + + for(i = 256; i > 0; i--){ + *(mattab) = (tot >> 16); + mattab += 3; + tot += ival; + } +} + + +static void cspfill(short *buf, short *fill, int x) +{ + short r,g,b; + + b = fill[0]; + g = fill[1]; + r = fill[2]; + for (;x>0;x--){ + buf[0] = b; + buf[1] = g; + buf[2] = r; + buf += 3; + } +} + + +static void cspadd(short *buf, short cont[][3], unsigned char *rect, int x) +{ + short i; + for (;x>0;x--){ + i = *(rect); + rect += 4; + buf[0] += cont[i][0]; + buf[1] += cont[i][1]; + buf[2] += cont[i][2]; + buf += 3; + } +} + + +static void cspret(short *buf, unsigned char *rect, int x) +{ + int r,g,b; + + for(; x > 0; x--){ + b = buf[0]; + g = buf[1]; + r = buf[2]; + + if (b & 0x4000){ + if (b<0) rect[2]=0; + else rect[2]=255; + } else rect[2] = b >> 6; + + if (g & 0x4000){ + if (g<0) rect[1]=0; + else rect[1]=255; + } else rect[1] = g >> 6; + + if (r & 0x4000){ + if (r<0) rect[0]=0; + else rect[0]=255; + } else rect[0] = r >> 6; + + buf += 3; + rect += 4; + } +} + + +static void rotcspace(struct ImBuf *ibuf, short *cont_1, short *cont_2, short *cont_3, short *add) +{ + short x,y,*buf; + uchar *rect; + + x=ibuf->x; + rect= (uchar *)ibuf->rect; + + buf=(short *)malloc(x*3*sizeof(short)); + if (buf){ + for(y=ibuf->y;y>0;y--){ + cspfill(buf,add,x); + cspadd(buf,cont_1,rect+0,x); + cspadd(buf,cont_2,rect+1,x); + cspadd(buf,cont_3,rect+2,x); + cspret(buf,rect,x); + rect += x<<2; + } + free(buf); + } +} + + +void IMB_cspace(struct ImBuf *ibuf, float mat[][4]) +{ + short *cont_1,*cont_2,*cont_3,add[3]; + + cont_1=(short *)malloc(256*3*sizeof(short)); + cont_2=(short *)malloc(256*3*sizeof(short)); + cont_3=(short *)malloc(256*3*sizeof(short)); + + if (cont_1 && cont_2 && cont_3){ + + fillmattab(mat[0][0],cont_1); + fillmattab(mat[0][1],cont_1+1); + fillmattab(mat[0][2],cont_1+2); + + fillmattab(mat[1][0],cont_2); + fillmattab(mat[1][1],cont_2+1); + fillmattab(mat[1][2],cont_2+2); + + fillmattab(mat[2][0],cont_3); + fillmattab(mat[2][1],cont_3+1); + fillmattab(mat[2][2],cont_3+2); + + add[0] = (mat[3][0] * 64.0) + .5; + add[1] = (mat[3][1] * 64.0) + .5; + add[2] = (mat[3][2] * 64.0) + .5; + + rotcspace(ibuf, cont_1, cont_2, cont_3, add); + } + + if (cont_1) free(cont_1); + if (cont_2) free(cont_2); + if (cont_3) free(cont_3); +} + diff --git a/source/blender/imbuf/intern/data.c b/source/blender/imbuf/intern/data.c new file mode 100644 index 00000000000..ad9194cb80e --- /dev/null +++ b/source/blender/imbuf/intern/data.c @@ -0,0 +1,145 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * data.c + * + * $Id$ + */ + +#include "imbuf.h" +#include "matrix.h" + +/* +static short quadbase[31] = { + 150,133,117,102, + 88,75,63,52, + 42,33,25,18, + 12,7,3,0, + 3,7,12,18, + 25,33,42,52, + 63,75,88,102, + 117,133,150, +}; + +short *quadr = quadbase+15; +*/ +/* +main() +{ + ushort _quadr[511], *quadr; + int i, delta; + + quadr = _quadr + 255; + + delta = 0; + for (i = 0 ; i <= 255 ; i++){ + quadr[i] = quadr[-i] = delta; + delta += i + 3; + } + + delta = 0; + for (i = 0; i < 511; i++){ + printf("%6d, ", _quadr[i]); + delta++; + if (delta == 8){ + delta = 0; + printf("\n"); + } + } +} +*/ + +static unsigned short quadbase[511] = { + 33150, 32893, 32637, 32382, 32128, 31875, 31623, 31372, + 31122, 30873, 30625, 30378, 30132, 29887, 29643, 29400, + 29158, 28917, 28677, 28438, 28200, 27963, 27727, 27492, + 27258, 27025, 26793, 26562, 26332, 26103, 25875, 25648, + 25422, 25197, 24973, 24750, 24528, 24307, 24087, 23868, + 23650, 23433, 23217, 23002, 22788, 22575, 22363, 22152, + 21942, 21733, 21525, 21318, 21112, 20907, 20703, 20500, + 20298, 20097, 19897, 19698, 19500, 19303, 19107, 18912, + 18718, 18525, 18333, 18142, 17952, 17763, 17575, 17388, + 17202, 17017, 16833, 16650, 16468, 16287, 16107, 15928, + 15750, 15573, 15397, 15222, 15048, 14875, 14703, 14532, + 14362, 14193, 14025, 13858, 13692, 13527, 13363, 13200, + 13038, 12877, 12717, 12558, 12400, 12243, 12087, 11932, + 11778, 11625, 11473, 11322, 11172, 11023, 10875, 10728, + 10582, 10437, 10293, 10150, 10008, 9867, 9727, 9588, + 9450, 9313, 9177, 9042, 8908, 8775, 8643, 8512, + 8382, 8253, 8125, 7998, 7872, 7747, 7623, 7500, + 7378, 7257, 7137, 7018, 6900, 6783, 6667, 6552, + 6438, 6325, 6213, 6102, 5992, 5883, 5775, 5668, + 5562, 5457, 5353, 5250, 5148, 5047, 4947, 4848, + 4750, 4653, 4557, 4462, 4368, 4275, 4183, 4092, + 4002, 3913, 3825, 3738, 3652, 3567, 3483, 3400, + 3318, 3237, 3157, 3078, 3000, 2923, 2847, 2772, + 2698, 2625, 2553, 2482, 2412, 2343, 2275, 2208, + 2142, 2077, 2013, 1950, 1888, 1827, 1767, 1708, + 1650, 1593, 1537, 1482, 1428, 1375, 1323, 1272, + 1222, 1173, 1125, 1078, 1032, 987, 943, 900, + 858, 817, 777, 738, 700, 663, 627, 592, + 558, 525, 493, 462, 432, 403, 375, 348, + 322, 297, 273, 250, 228, 207, 187, 168, + 150, 133, 117, 102, 88, 75, 63, 52, + 42, 33, 25, 18, 12, 7, 3, 0, + 3, 7, 12, 18, 25, 33, 42, 52, + 63, 75, 88, 102, 117, 133, 150, 168, + 187, 207, 228, 250, 273, 297, 322, 348, + 375, 403, 432, 462, 493, 525, 558, 592, + 627, 663, 700, 738, 777, 817, 858, 900, + 943, 987, 1032, 1078, 1125, 1173, 1222, 1272, + 1323, 1375, 1428, 1482, 1537, 1593, 1650, 1708, + 1767, 1827, 1888, 1950, 2013, 2077, 2142, 2208, + 2275, 2343, 2412, 2482, 2553, 2625, 2698, 2772, + 2847, 2923, 3000, 3078, 3157, 3237, 3318, 3400, + 3483, 3567, 3652, 3738, 3825, 3913, 4002, 4092, + 4183, 4275, 4368, 4462, 4557, 4653, 4750, 4848, + 4947, 5047, 5148, 5250, 5353, 5457, 5562, 5668, + 5775, 5883, 5992, 6102, 6213, 6325, 6438, 6552, + 6667, 6783, 6900, 7018, 7137, 7257, 7378, 7500, + 7623, 7747, 7872, 7998, 8125, 8253, 8382, 8512, + 8643, 8775, 8908, 9042, 9177, 9313, 9450, 9588, + 9727, 9867, 10008, 10150, 10293, 10437, 10582, 10728, + 10875, 11023, 11172, 11322, 11473, 11625, 11778, 11932, + 12087, 12243, 12400, 12558, 12717, 12877, 13038, 13200, + 13363, 13527, 13692, 13858, 14025, 14193, 14362, 14532, + 14703, 14875, 15048, 15222, 15397, 15573, 15750, 15928, + 16107, 16287, 16468, 16650, 16833, 17017, 17202, 17388, + 17575, 17763, 17952, 18142, 18333, 18525, 18718, 18912, + 19107, 19303, 19500, 19698, 19897, 20097, 20298, 20500, + 20703, 20907, 21112, 21318, 21525, 21733, 21942, 22152, + 22363, 22575, 22788, 23002, 23217, 23433, 23650, 23868, + 24087, 24307, 24528, 24750, 24973, 25197, 25422, 25648, + 25875, 26103, 26332, 26562, 26793, 27025, 27258, 27492, + 27727, 27963, 28200, 28438, 28677, 28917, 29158, 29400, + 29643, 29887, 30132, 30378, 30625, 30873, 31122, 31372, + 31623, 31875, 32128, 32382, 32637, 32893, 33150, +}; + +unsigned short *quadr = quadbase + 255; diff --git a/source/blender/imbuf/intern/dither.c b/source/blender/imbuf/intern/dither.c new file mode 100644 index 00000000000..608332af244 --- /dev/null +++ b/source/blender/imbuf/intern/dither.c @@ -0,0 +1,133 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * dither.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +void IMB_dit0(struct ImBuf * ibuf, short ofs, short bits) +{ + int x, y, and, add, pix; + uchar *rect; + + rect= (uchar *)ibuf->rect; + rect +=ofs; + + bits = 8 - bits; + and = ~((1 << bits)-1); + add = 1 << (bits - 1); + + for (y = ibuf->y; y > 0; y--){ + for (x = ibuf->x; x > 0; x--) { + pix = *rect + add; + if (pix > 255) pix = 255; + *rect = pix & and; + rect += 4; + } + } +} + +void IMB_dit2(struct ImBuf * ibuf, short ofs, short bits) +{ + short x,y,pix,and,add1,add2; + uchar *rect; + uchar dit[4]; + + rect= (uchar *)ibuf->rect; + rect +=ofs; + + bits = 8 - bits; + and = ~((1<<bits)-1); + bits -= 2; + + ofs = 0; + + switch(ofs){ + case 3: + break; + case 2: + dit[0]=0; + dit[1]=1; + dit[2]=2; + dit[3]=3; + break; + case 1: + dit[0]=3; + dit[1]=1; + dit[2]=0; + dit[3]=2; + break; + case 0: + dit[0]=0; + dit[1]=2; + dit[2]=3; + dit[3]=1; + break; + } + + if (bits < 0){ + dit[0] >>= -bits; + dit[1] >>= -bits; + dit[2] >>= -bits; + dit[3] >>= -bits; + } else{ + dit[0] <<= bits; + dit[1] <<= bits; + dit[2] <<= bits; + dit[3] <<= bits; + } + + for(y=ibuf->y;y>0;y--){ + if(y & 1){ + add1=dit[0]; + add2=dit[1]; + } + else{ + add1=dit[2]; + add2=dit[3]; + } + for(x=ibuf->x;x>0;x--){ + pix = *rect; + if (x & 1) pix += add1; + else pix += add2; + + if (pix>255) pix=255; + *rect = pix & and; + rect += 4; + } + } +} diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c new file mode 100644 index 00000000000..81484ef6dfc --- /dev/null +++ b/source/blender/imbuf/intern/divers.c @@ -0,0 +1,119 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * allocimbuf.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_divers.h" + + +void imb_checkncols(struct ImBuf *ibuf) +/* struct ImBuf *ibuf; */ +{ + unsigned int i; + + if (ibuf==0) return; + + if (IS_amiga(ibuf)){ + if (IS_ham(ibuf)){ + if (ibuf->depth == 0) ibuf->depth = 6; + ibuf->mincol = 0; + ibuf->maxcol = 1 << (ibuf->depth - 2); + /*printf("%d %d\n", ibuf->maxcol, ibuf->depth);*/ + return; + } else if (IS_hbrite(ibuf)){ + ibuf->mincol = 0; + ibuf->maxcol = 64; + ibuf->depth = 6; + return; + } + } + + if (ibuf->maxcol == 0){ + if (ibuf->depth <= 8){ + ibuf->mincol = 0; + ibuf->maxcol = (1 << ibuf->depth); + return; + } else if (ibuf->depth == 0){ + ibuf->depth = 5; + ibuf->mincol = 0; + ibuf->maxcol = 32; + } + return; + } else { + /* ibuf->maxcol is bepalend voor de diepte */ + for (i=1 ; ibuf->maxcol > (1 << i); i++); + ibuf->depth = i; + return; + } +} + + +void IMB_de_interlace(struct ImBuf *ibuf) +{ + struct ImBuf * tbuf1, * tbuf2; +/* extern rectcpy(); */ + + if (ibuf == 0) return; + if (ibuf->flags & IB_fields) return; + ibuf->flags |= IB_fields; + + if (ibuf->rect) { + /* kopieen aanmaken */ + tbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0); + tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0); + + ibuf->x *= 2; +/* Functions need more args :( */ +/* rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, rectcpy); */ +/* rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, rectcpy); */ + IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); + + ibuf->x /= 2; +/* rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, rectcpy); */ +/* rectop(ibuf, tbuf2, 0, tbuf2->y, 0, 0, 32767, 32767, rectcpy); */ + IMB_rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectop(ibuf, tbuf2, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0); + + IMB_freeImBuf(tbuf1); + IMB_freeImBuf(tbuf2); + } + ibuf->y /= 2; +} + diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c new file mode 100644 index 00000000000..dfc6e26e68a --- /dev/null +++ b/source/blender/imbuf/intern/filter.c @@ -0,0 +1,144 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * filter.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_filter.h" + + +/************************************************************************/ +/* FILTERS */ +/************************************************************************/ + +static void filtrow(unsigned char *point, int x) +{ + unsigned int c1,c2,c3,error; + + if (x>1){ + c1 = c2 = *point; + error = 2; + for(x--;x>0;x--){ + c3 = point[4]; + c1 += (c2<<1) + c3 + error; + error = c1 & 3; + *point = c1 >> 2; + point += 4; + c1=c2; + c2=c3; + } + *point = (c1 + (c2<<1) + c2 + error) >> 2; + } +} + + +static void filtcolum(unsigned char *point, int y, int skip) +{ + unsigned int c1,c2,c3,error; + unsigned char *point2; + + if (y>1){ + c1 = c2 = *point; + point2 = point; + error = 2; + for(y--;y>0;y--){ + point2 += skip; + c3 = *point2; + c1 += (c2<<1) + c3 +error; + error = c1 & 3; + *point = c1 >> 2; + point=point2; + c1=c2; + c2=c3; + } + *point = (c1 + (c2<<1) + c2 + error) >> 2; + } +} + + +void IMB_filtery(struct ImBuf *ibuf) +{ + unsigned char *point; + short x,y,skip; + + point = (unsigned char *)ibuf->rect; + x = ibuf->x; + y = ibuf->y; + skip = x<<2; + + for (;x>0;x--){ + if (ibuf->depth > 24) filtcolum(point,y,skip); + point++; + filtcolum(point,y,skip); + point++; + filtcolum(point,y,skip); + point++; + filtcolum(point,y,skip); + point++; + } +} + + +void imb_filterx(struct ImBuf *ibuf) +{ + unsigned char *point; + short x,y,skip; + + point = (unsigned char *)ibuf->rect; + x = ibuf->x; + y = ibuf->y; + skip = (x<<2) - 3; + + for (;y>0;y--){ + if (ibuf->depth > 24) filtrow(point,x); + point++; + filtrow(point,x); + point++; + filtrow(point,x); + point++; + filtrow(point,x); + point+=skip; + } +} + + +void IMB_filter(struct ImBuf *ibuf) +{ + IMB_filtery(ibuf); + imb_filterx(ibuf); +} diff --git a/source/blender/imbuf/intern/ham.c b/source/blender/imbuf/intern/ham.c new file mode 100644 index 00000000000..f9c6cf996a0 --- /dev/null +++ b/source/blender/imbuf/intern/ham.c @@ -0,0 +1,290 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ham.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_cmap.h" +#include "IMB_hamx.h" +#include "IMB_ham.h" + +extern short alpha_col0; + +#define HAMB 0x0100 +#define HAMG 0x0400 +#define HAMR 0x0200 +#define HAMC 0x1000 +#define HAMFREE 0x2000 + +static void addhamdither(short x, unsigned char *dit, + short dmax, unsigned char *rgb, + unsigned short *ham, + short type, short round, short shift) +/* short x, dmax, type, round, shift; */ +/* uchar *dit, *rgb; */ +/* unsigned short *ham; */ +{ + short dx = 0; + short c1, c2; + + for (;x>0;x--){ + if (ham[0] & (HAMFREE | type)){ + c2 = c1 = *rgb; + + /* wrap dither */ + while (dx >= dmax) dx -= dmax; + + c1 += dit[dx]; + if (c1 > 255) c1 = 255; + c2 += round; + if (c2 > 255) c2 = 255; + + if (c1 != c2){ + c1 >>= shift; c2 >>= shift; + if (ham[1] & HAMFREE){ + ham[0] = type + c1; + ham[1] = type + c2; + } else if (ham[1] & type){ + ham[0] = type + c1; + } else if ((ham[2] & (type | HAMFREE)) == type){ + ham[0] = type + c1; + } else if ((ham[1] & HAMC) | (ham[2] & HAMC)){ + ham[0] = type + c1; + } + } + } + rgb += 4; + ham ++; + dx ++; + } +} + +static void convhamscanl(short x, short y, + unsigned char *rgbbase, + unsigned char coltab[][4], + short *deltab, + short bits) +/* short x, y, bits; */ +/* uchar *rgbbase; */ +/* uchar coltab[][4]; */ +/* short *deltab; */ +{ + int a, r, g, b, lr, lg, lb, dr, dg, db, col, fout, type, x2; + int round, shift; + uchar *rgb, dit[2]; + unsigned short *ham, *hambase; + + /* Opzet: + eerst wordt het gehele plaatje afgelopen, waarbij kleurovergangen gecodeerd + worden: FGRB XXXX XXXX + F - vrije kleurwaarde, mag door ieder veranderd worden + G/R/B - groen/rood/blauw ham overgang, alleen door die kleur te veranderen + XXXX XXXX - N bits waarde. + + 0000 XXXX XXXX is palet kleur. + + daarna wordt eerst de groen dither toegevoegd, dan de rood dither en + tenslotte wordt blauwdither toegevoegd + */ + + if ((hambase = (unsigned short *) malloc((x+4) * sizeof(unsigned short)))==0) return; + + lb = coltab[0][1]; + lg = coltab[0][2]; + lr = coltab[0][3]; + type = col = 0; + + ham = hambase; + rgb = rgbbase; + + shift = 8 - bits; + round = 1 << (shift - 1); + + /* om te voorkomen dat er 'ruis' ontstaat aan het einde van de regel */ + for (x2 = 3; x2 >= 0; x2 --) hambase[x + x2] = HAMFREE; + + for (x2 = x ;x2 > 0; x2--){ + r = rgb[0] + round; + g = rgb[1] + round; + b = rgb[2] + round; + a = rgb[3]; + + if (a < 128 && alpha_col0) { + a = 1; + } else a = 0; + + if (b > 255) b = 255; + if (g > 255) { + g = 255; + } + if (r > 255) r = 255; + + r >>= shift; + g >>= shift; + b >>= shift; + + if ((b-lb) | (g-lg) | (r-lr) | a){ + if (a) { + col = 0; + type = HAMC; + } else { + col = ((b << (2 * bits)) + (g << bits) + r) << 1; + fout = deltab[col + 1]; + col = deltab[col]; + type = HAMC; + + dr = quadr[lr-r]; + dg = quadr[lg-g]; + db = quadr[lb-b]; + + if ((dr+dg) <= fout){ + fout = dr+dg; + col = b; + type = HAMB; + } + if ((dg+db) <= fout){ + fout = dg+db; + col = r; + type = HAMR; + } + if ((dr+db) <= fout){ + fout = dr+db; + col = g; + type = HAMG; + } + } + + switch(type){ + case HAMG: + lg = g; + break; + case HAMR: + lr = r; + break; + case HAMB: + lb = b; + break; + default: + lb = coltab[col][1]; + lg = coltab[col][2]; + lr = coltab[col][3]; + } + *ham = type + col; + } else *ham = HAMG + HAMFREE + g; + + rgb += 4; + ham ++; + } + + + if (y & 1){ + dit[0] = 0 << (shift - 2); + dit[1] = 3 << (shift - 2); + } else { + dit[0] = 2 << (shift - 2); + dit[1] = 1 << (shift - 2); + } + + addhamdither(x,dit,2,rgbbase+2,hambase,HAMG, round, shift); + + if ((y & 1)==0){ + dit[0] = 3 << (shift - 2); + dit[1] = 0 << (shift - 2); + } else { + dit[0] = 1 << (shift - 2); + dit[1] = 2 << (shift - 2); + } + + addhamdither(x,dit,2,rgbbase+3,hambase,HAMR, round, shift); + addhamdither(x,dit,2,rgbbase+1,hambase,HAMB, round, shift); + + + ham = hambase; + rgb = rgbbase; + rgb += 3; + + for (x2=x;x2>0;x2--){ + type = *(ham++); + if (type & HAMG) type |= HAMR | HAMB; + + *rgb = (type & 0xff) | ((type & (HAMR | HAMB)) >> shift); + rgb += 4; + } + + free (hambase); +} + + +short imb_converttoham(struct ImBuf *ibuf) +/* struct ImBuf* ibuf; */ +{ + unsigned int coltab[256],*rect; + short x,y,* deltab; + int mincol; + + memcpy(coltab,ibuf->cmap,4 * ibuf->maxcol); + + mincol = ibuf->mincol; + if (alpha_col0 && mincol == 0) mincol = 1; + + if (ibuf->ftype == AN_hamx) { + deltab = imb_coldeltatab((uchar *) coltab, 0, ibuf->maxcol, 4); + } else { + ibuf->cbits = ibuf->depth - 2; + imb_losecmapbits(ibuf, coltab); + deltab = imb_coldeltatab((uchar *) coltab, mincol, ibuf->maxcol, ibuf->cbits); + } + + rect = ibuf->rect; + x=ibuf->x; + y=ibuf->y; + + if (ibuf->ftype == AN_hamx){ + IMB_dit2(ibuf, 2, 4); + IMB_dit2(ibuf, 1, 4); + IMB_dit2(ibuf, 0, 4); + imb_convhamx(ibuf, coltab, deltab); + } else { + for(;y > 0; y--){ + convhamscanl(x, y, rect, coltab, deltab, ibuf->cbits); + rect += x; + } + } + + return (TRUE); +} diff --git a/source/blender/imbuf/intern/hamx.c b/source/blender/imbuf/intern/hamx.c new file mode 100644 index 00000000000..b297548fde6 --- /dev/null +++ b/source/blender/imbuf/intern/hamx.c @@ -0,0 +1,593 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * hamx.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" +#ifdef WIN32 +#include "BLI_winstuff.h" +#include <io.h> +#endif + + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_filter.h" +#include "IMB_ham.h" +#include "IMB_hamx.h" + +/* actually hard coded endianness */ +#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) +#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0]) +#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff)) +#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff)) + +/* more endianness... should move to a separate file... */ +#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +#define GET_ID GET_BIG_LONG +#define LITTLE_LONG SWAP_LONG +#else +#define GET_ID GET_LITTLE_LONG +#define LITTLE_LONG ENDIAN_NOP +#endif + +#ifndef ABS +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#endif + +static uchar hamx_array_char[] = { + 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, + 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, 0x00,0x00,0xFF,0xFF, + 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, 0x00,0xFF,0x00,0xFF, + 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, + 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, 0x00,0xFF,0xFF,0x00, + + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + + 0x00,0x00,0x00,0x00, 0x00,0x10,0x00,0x00, 0x00,0x20,0x00,0x00, 0x00,0x30,0x00,0x00, 0x00,0x40,0x00,0x00, 0x00,0x50,0x00,0x00, 0x00,0x60,0x00,0x00, 0x00,0x70,0x00,0x00, + 0x00,0x80,0x00,0x00, 0x00,0x90,0x00,0x00, 0x00,0xA0,0x00,0x00, 0x00,0xB0,0x00,0x00, 0x00,0xC0,0x00,0x00, 0x00,0xD0,0x00,0x00, 0x00,0xE0,0x00,0x00, 0x00,0xF0,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x10,0x00, 0x00,0x00,0x20,0x00, 0x00,0x00,0x30,0x00, 0x00,0x00,0x40,0x00, 0x00,0x00,0x50,0x00, 0x00,0x00,0x60,0x00, 0x00,0x00,0x70,0x00, + 0x00,0x00,0x80,0x00, 0x00,0x00,0x90,0x00, 0x00,0x00,0xA0,0x00, 0x00,0x00,0xB0,0x00, 0x00,0x00,0xC0,0x00, 0x00,0x00,0xD0,0x00, 0x00,0x00,0xE0,0x00, 0x00,0x00,0xF0,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x10, 0x00,0x00,0x00,0x20, 0x00,0x00,0x00,0x30, 0x00,0x00,0x00,0x40, 0x00,0x00,0x00,0x50, 0x00,0x00,0x00,0x60, 0x00,0x00,0x00,0x70, + 0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x90, 0x00,0x00,0x00,0xA0, 0x00,0x00,0x00,0xB0, 0x00,0x00,0x00,0xC0, 0x00,0x00,0x00,0xD0, 0x00,0x00,0x00,0xE0, 0x00,0x00,0x00,0xF0, + + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x30, 0x00,0x00,0x00,0x60, 0x00,0x00,0x00,0x90, 0x00,0x00,0x00,0xC0, 0x00,0x00,0x00,0xF0, + 0x00,0x00,0x20,0x00, 0x00,0x00,0x20,0x30, 0x00,0x00,0x20,0x60, 0x00,0x00,0x20,0x90, 0x00,0x00,0x20,0xC0, 0x00,0x00,0x20,0xF0, + 0x00,0x00,0x40,0x00, 0x00,0x00,0x40,0x30, 0x00,0x00,0x40,0x60, 0x00,0x00,0x40,0x90, 0x00,0x00,0x40,0xC0, 0x00,0x00,0x40,0xF0, + 0x00,0x00,0x60,0x00, 0x00,0x00,0x60,0x30, 0x00,0x00,0x60,0x60, 0x00,0x00,0x60,0x90, 0x00,0x00,0x60,0xC0, 0x00,0x00,0x60,0xF0, + 0x00,0x00,0x90,0x00, 0x00,0x00,0x90,0x30, 0x00,0x00,0x90,0x60, 0x00,0x00,0x90,0x90, 0x00,0x00,0x90,0xC0, 0x00,0x00,0x90,0xF0, + 0x00,0x00,0xB0,0x00, 0x00,0x00,0xB0,0x30, 0x00,0x00,0xB0,0x60, 0x00,0x00,0xB0,0x90, 0x00,0x00,0xB0,0xC0, 0x00,0x00,0xB0,0xF0, + 0x00,0x00,0xD0,0x00, 0x00,0x00,0xD0,0x30, 0x00,0x00,0xD0,0x60, 0x00,0x00,0xD0,0x90, 0x00,0x00,0xD0,0xC0, 0x00,0x00,0xD0,0xF0, + 0x00,0x00,0xF0,0x00, 0x00,0x00,0xF0,0x30, 0x00,0x00,0xF0,0x60, 0x00,0x00,0xF0,0x90, 0x00,0x00,0xF0,0xC0, 0x00,0x00,0xF0,0xF0, + 0x00,0x50,0x00,0x00, 0x00,0x50,0x00,0x30, 0x00,0x50,0x00,0x60, 0x00,0x50,0x00,0x90, 0x00,0x50,0x00,0xC0, 0x00,0x50,0x00,0xF0, + 0x00,0x50,0x20,0x00, 0x00,0x50,0x20,0x30, 0x00,0x50,0x20,0x60, 0x00,0x50,0x20,0x90, 0x00,0x50,0x20,0xC0, 0x00,0x50,0x20,0xF0, + 0x00,0x50,0x40,0x00, 0x00,0x50,0x40,0x30, 0x00,0x50,0x40,0x60, 0x00,0x50,0x40,0x90, 0x00,0x50,0x40,0xC0, 0x00,0x50,0x40,0xF0, + 0x00,0x50,0x60,0x00, 0x00,0x50,0x60,0x30, 0x00,0x50,0x60,0x60, 0x00,0x50,0x60,0x90, 0x00,0x50,0x60,0xC0, 0x00,0x50,0x60,0xF0, + 0x00,0x50,0x90,0x00, 0x00,0x50,0x90,0x30, 0x00,0x50,0x90,0x60, 0x00,0x50,0x90,0x90, 0x00,0x50,0x90,0xC0, 0x00,0x50,0x90,0xF0, + 0x00,0x50,0xB0,0x00, 0x00,0x50,0xB0,0x30, 0x00,0x50,0xB0,0x60, 0x00,0x50,0xB0,0x90, 0x00,0x50,0xB0,0xC0, 0x00,0x50,0xB0,0xF0, + 0x00,0x50,0xD0,0x00, 0x00,0x50,0xD0,0x30, 0x00,0x50,0xD0,0x60, 0x00,0x50,0xD0,0x90, 0x00,0x50,0xD0,0xC0, 0x00,0x50,0xD0,0xF0, + 0x00,0x50,0xF0,0x00, 0x00,0x50,0xF0,0x30, 0x00,0x50,0xF0,0x60, 0x00,0x50,0xF0,0x90, 0x00,0x50,0xF0,0xC0, 0x00,0x50,0xF0,0xF0, + 0x00,0xA0,0x00,0x00, 0x00,0xA0,0x00,0x30, 0x00,0xA0,0x00,0x60, 0x00,0xA0,0x00,0x90, 0x00,0xA0,0x00,0xC0, 0x00,0xA0,0x00,0xF0, + 0x00,0xA0,0x20,0x00, 0x00,0xA0,0x20,0x30, 0x00,0xA0,0x20,0x60, 0x00,0xA0,0x20,0x90, 0x00,0xA0,0x20,0xC0, 0x00,0xA0,0x20,0xF0, + 0x00,0xA0,0x40,0x00, 0x00,0xA0,0x40,0x30, 0x00,0xA0,0x40,0x60, 0x00,0xA0,0x40,0x90, 0x00,0xA0,0x40,0xC0, 0x00,0xA0,0x40,0xF0, + 0x00,0xA0,0x60,0x00, 0x00,0xA0,0x60,0x30, 0x00,0xA0,0x60,0x60, 0x00,0xA0,0x60,0x90, 0x00,0xA0,0x60,0xC0, 0x00,0xA0,0x60,0xF0, + 0x00,0xA0,0x90,0x00, 0x00,0xA0,0x90,0x30, 0x00,0xA0,0x90,0x60, 0x00,0xA0,0x90,0x90, 0x00,0xA0,0x90,0xC0, 0x00,0xA0,0x90,0xF0, + 0x00,0xA0,0xB0,0x00, 0x00,0xA0,0xB0,0x30, 0x00,0xA0,0xB0,0x60, 0x00,0xA0,0xB0,0x90, 0x00,0xA0,0xB0,0xC0, 0x00,0xA0,0xB0,0xF0, + 0x00,0xA0,0xD0,0x00, 0x00,0xA0,0xD0,0x30, 0x00,0xA0,0xD0,0x60, 0x00,0xA0,0xD0,0x90, 0x00,0xA0,0xD0,0xC0, 0x00,0xA0,0xD0,0xF0, + 0x00,0xA0,0xF0,0x00, 0x00,0xA0,0xF0,0x30, 0x00,0xA0,0xF0,0x60, 0x00,0xA0,0xF0,0x90, 0x00,0xA0,0xF0,0xC0, 0x00,0xA0,0xF0,0xF0, + 0x00,0xF0,0x00,0x00, 0x00,0xF0,0x00,0x30, 0x00,0xF0,0x00,0x60, 0x00,0xF0,0x00,0x90, 0x00,0xF0,0x00,0xC0, 0x00,0xF0,0x00,0xF0, + 0x00,0xF0,0x20,0x00, 0x00,0xF0,0x20,0x30, 0x00,0xF0,0x20,0x60, 0x00,0xF0,0x20,0x90, 0x00,0xF0,0x20,0xC0, 0x00,0xF0,0x20,0xF0, + 0x00,0xF0,0x40,0x00, 0x00,0xF0,0x40,0x30, 0x00,0xF0,0x40,0x60, 0x00,0xF0,0x40,0x90, 0x00,0xF0,0x40,0xC0, 0x00,0xF0,0x40,0xF0, + 0x00,0xF0,0x60,0x00, 0x00,0xF0,0x60,0x30, 0x00,0xF0,0x60,0x60, 0x00,0xF0,0x60,0x90, 0x00,0xF0,0x60,0xC0, 0x00,0xF0,0x60,0xF0, + 0x00,0xF0,0x90,0x00, 0x00,0xF0,0x90,0x30, 0x00,0xF0,0x90,0x60, 0x00,0xF0,0x90,0x90, 0x00,0xF0,0x90,0xC0, 0x00,0xF0,0x90,0xF0, + 0x00,0xF0,0xB0,0x00, 0x00,0xF0,0xB0,0x30, 0x00,0xF0,0xB0,0x60, 0x00,0xF0,0xB0,0x90, 0x00,0xF0,0xB0,0xC0, 0x00,0xF0,0xB0,0xF0, + 0x00,0xF0,0xD0,0x00, 0x00,0xF0,0xD0,0x30, 0x00,0xF0,0xD0,0x60, 0x00,0xF0,0xD0,0x90, 0x00,0xF0,0xD0,0xC0, 0x00,0xF0,0xD0,0xF0, + 0x00,0xF0,0xF0,0x00, 0x00,0xF0,0xF0,0x30, 0x00,0xF0,0xF0,0x60, 0x00,0xF0,0xF0,0x90, 0x00,0xF0,0xF0,0xC0, 0x00,0xF0,0xF0,0xF0, + + 0x00,0x10,0x10,0x10, 0x00,0x20,0x20,0x20, 0x00,0x30,0x30,0x30, 0x00,0x40,0x40,0x40, + 0x00,0x50,0x50,0x50, 0x00,0x60,0x60,0x60, 0x00,0x70,0x70,0x70, 0x00,0x80,0x80,0x80, + 0x00,0x90,0x90,0x90, 0x00,0xA0,0xA0,0xA0, 0x00,0xB0,0xB0,0xB0, 0x00,0xC0,0xC0,0xC0, + 0x00,0xD0,0xD0,0xD0, 0x00,0xE0,0xE0,0xE0 +}; + +static int * hamx_array = (int *) (hamx_array_char); + +static uchar cmap_hamx[] = { + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x30, 0x00,0x00,0x00,0x60, 0x00,0x00,0x00,0x90, 0x00,0x00,0x00,0xC0, 0x00,0x00,0x00,0xF0, + 0x00,0x00,0x20,0x00, 0x00,0x00,0x20,0x30, 0x00,0x00,0x20,0x60, 0x00,0x00,0x20,0x90, 0x00,0x00,0x20,0xC0, 0x00,0x00,0x20,0xF0, + 0x00,0x00,0x40,0x00, 0x00,0x00,0x40,0x30, 0x00,0x00,0x40,0x60, 0x00,0x00,0x40,0x90, 0x00,0x00,0x40,0xC0, 0x00,0x00,0x40,0xF0, + 0x00,0x00,0x60,0x00, 0x00,0x00,0x60,0x30, 0x00,0x00,0x60,0x60, 0x00,0x00,0x60,0x90, 0x00,0x00,0x60,0xC0, 0x00,0x00,0x60,0xF0, + 0x00,0x00,0x90,0x00, 0x00,0x00,0x90,0x30, 0x00,0x00,0x90,0x60, 0x00,0x00,0x90,0x90, 0x00,0x00,0x90,0xC0, 0x00,0x00,0x90,0xF0, + 0x00,0x00,0xB0,0x00, 0x00,0x00,0xB0,0x30, 0x00,0x00,0xB0,0x60, 0x00,0x00,0xB0,0x90, 0x00,0x00,0xB0,0xC0, 0x00,0x00,0xB0,0xF0, + 0x00,0x00,0xD0,0x00, 0x00,0x00,0xD0,0x30, 0x00,0x00,0xD0,0x60, 0x00,0x00,0xD0,0x90, 0x00,0x00,0xD0,0xC0, 0x00,0x00,0xD0,0xF0, + 0x00,0x00,0xF0,0x00, 0x00,0x00,0xF0,0x30, 0x00,0x00,0xF0,0x60, 0x00,0x00,0xF0,0x90, 0x00,0x00,0xF0,0xC0, 0x00,0x00,0xF0,0xF0, + 0x00,0x50,0x00,0x00, 0x00,0x50,0x00,0x30, 0x00,0x50,0x00,0x60, 0x00,0x50,0x00,0x90, 0x00,0x50,0x00,0xC0, 0x00,0x50,0x00,0xF0, + 0x00,0x50,0x20,0x00, 0x00,0x50,0x20,0x30, 0x00,0x50,0x20,0x60, 0x00,0x50,0x20,0x90, 0x00,0x50,0x20,0xC0, 0x00,0x50,0x20,0xF0, + 0x00,0x50,0x40,0x00, 0x00,0x50,0x40,0x30, 0x00,0x50,0x40,0x60, 0x00,0x50,0x40,0x90, 0x00,0x50,0x40,0xC0, 0x00,0x50,0x40,0xF0, + 0x00,0x50,0x60,0x00, 0x00,0x50,0x60,0x30, 0x00,0x50,0x60,0x60, 0x00,0x50,0x60,0x90, 0x00,0x50,0x60,0xC0, 0x00,0x50,0x60,0xF0, + 0x00,0x50,0x90,0x00, 0x00,0x50,0x90,0x30, 0x00,0x50,0x90,0x60, 0x00,0x50,0x90,0x90, 0x00,0x50,0x90,0xC0, 0x00,0x50,0x90,0xF0, + 0x00,0x50,0xB0,0x00, 0x00,0x50,0xB0,0x30, 0x00,0x50,0xB0,0x60, 0x00,0x50,0xB0,0x90, 0x00,0x50,0xB0,0xC0, 0x00,0x50,0xB0,0xF0, + 0x00,0x50,0xD0,0x00, 0x00,0x50,0xD0,0x30, 0x00,0x50,0xD0,0x60, 0x00,0x50,0xD0,0x90, 0x00,0x50,0xD0,0xC0, 0x00,0x50,0xD0,0xF0, + 0x00,0x50,0xF0,0x00, 0x00,0x50,0xF0,0x30, 0x00,0x50,0xF0,0x60, 0x00,0x50,0xF0,0x90, 0x00,0x50,0xF0,0xC0, 0x00,0x50,0xF0,0xF0, + 0x00,0xA0,0x00,0x00, 0x00,0xA0,0x00,0x30, 0x00,0xA0,0x00,0x60, 0x00,0xA0,0x00,0x90, 0x00,0xA0,0x00,0xC0, 0x00,0xA0,0x00,0xF0, + 0x00,0xA0,0x20,0x00, 0x00,0xA0,0x20,0x30, 0x00,0xA0,0x20,0x60, 0x00,0xA0,0x20,0x90, 0x00,0xA0,0x20,0xC0, 0x00,0xA0,0x20,0xF0, + 0x00,0xA0,0x40,0x00, 0x00,0xA0,0x40,0x30, 0x00,0xA0,0x40,0x60, 0x00,0xA0,0x40,0x90, 0x00,0xA0,0x40,0xC0, 0x00,0xA0,0x40,0xF0, + 0x00,0xA0,0x60,0x00, 0x00,0xA0,0x60,0x30, 0x00,0xA0,0x60,0x60, 0x00,0xA0,0x60,0x90, 0x00,0xA0,0x60,0xC0, 0x00,0xA0,0x60,0xF0, + 0x00,0xA0,0x90,0x00, 0x00,0xA0,0x90,0x30, 0x00,0xA0,0x90,0x60, 0x00,0xA0,0x90,0x90, 0x00,0xA0,0x90,0xC0, 0x00,0xA0,0x90,0xF0, + 0x00,0xA0,0xB0,0x00, 0x00,0xA0,0xB0,0x30, 0x00,0xA0,0xB0,0x60, 0x00,0xA0,0xB0,0x90, 0x00,0xA0,0xB0,0xC0, 0x00,0xA0,0xB0,0xF0, + 0x00,0xA0,0xD0,0x00, 0x00,0xA0,0xD0,0x30, 0x00,0xA0,0xD0,0x60, 0x00,0xA0,0xD0,0x90, 0x00,0xA0,0xD0,0xC0, 0x00,0xA0,0xD0,0xF0, + 0x00,0xA0,0xF0,0x00, 0x00,0xA0,0xF0,0x30, 0x00,0xA0,0xF0,0x60, 0x00,0xA0,0xF0,0x90, 0x00,0xA0,0xF0,0xC0, 0x00,0xA0,0xF0,0xF0, + 0x00,0xF0,0x00,0x00, 0x00,0xF0,0x00,0x30, 0x00,0xF0,0x00,0x60, 0x00,0xF0,0x00,0x90, 0x00,0xF0,0x00,0xC0, 0x00,0xF0,0x00,0xF0, + 0x00,0xF0,0x20,0x00, 0x00,0xF0,0x20,0x30, 0x00,0xF0,0x20,0x60, 0x00,0xF0,0x20,0x90, 0x00,0xF0,0x20,0xC0, 0x00,0xF0,0x20,0xF0, + 0x00,0xF0,0x40,0x00, 0x00,0xF0,0x40,0x30, 0x00,0xF0,0x40,0x60, 0x00,0xF0,0x40,0x90, 0x00,0xF0,0x40,0xC0, 0x00,0xF0,0x40,0xF0, + 0x00,0xF0,0x60,0x00, 0x00,0xF0,0x60,0x30, 0x00,0xF0,0x60,0x60, 0x00,0xF0,0x60,0x90, 0x00,0xF0,0x60,0xC0, 0x00,0xF0,0x60,0xF0, + 0x00,0xF0,0x90,0x00, 0x00,0xF0,0x90,0x30, 0x00,0xF0,0x90,0x60, 0x00,0xF0,0x90,0x90, 0x00,0xF0,0x90,0xC0, 0x00,0xF0,0x90,0xF0, + 0x00,0xF0,0xB0,0x00, 0x00,0xF0,0xB0,0x30, 0x00,0xF0,0xB0,0x60, 0x00,0xF0,0xB0,0x90, 0x00,0xF0,0xB0,0xC0, 0x00,0xF0,0xB0,0xF0, + 0x00,0xF0,0xD0,0x00, 0x00,0xF0,0xD0,0x30, 0x00,0xF0,0xD0,0x60, 0x00,0xF0,0xD0,0x90, 0x00,0xF0,0xD0,0xC0, 0x00,0xF0,0xD0,0xF0, + 0x00,0xF0,0xF0,0x00, 0x00,0xF0,0xF0,0x30, 0x00,0xF0,0xF0,0x60, 0x00,0xF0,0xF0,0x90, 0x00,0xF0,0xF0,0xC0, 0x00,0xF0,0xF0,0xF0, + 0x00,0x10,0x10,0x10, 0x00,0x20,0x20,0x20, 0x00,0x30,0x30,0x30, 0x00,0x40,0x40,0x40, 0x00,0x50,0x50,0x50, 0x00,0x60,0x60,0x60, + 0x00,0x70,0x70,0x70, 0x00,0x80,0x80,0x80, 0x00,0x90,0x90,0x90, 0x00,0xA0,0xA0,0xA0, 0x00,0xB0,0xB0,0xB0, 0x00,0xC0,0xC0,0xC0, + 0x00,0xD0,0xD0,0xD0, 0x00,0xE0,0xE0,0xE0 +}; + + +float adat_gamma = 1.0; +float adat_distort = 1.0; + +/* + * + * Nieuwe versie: + * + * 32 helderheden Y 15 direct te bereiken (zwart & wit zijn specials) + * 16 kleuren H ue + * 7 intensiteiten S aturation + * + * Totaal 3584 'verschillende' kleuren. Eerste 512 kleuren vrij. + * + * + */ + +void imb_convhamx(struct ImBuf *ibuf, unsigned char coltab[][4], short *deltab) +/* struct ImBuf *ibuf; */ +/* uchar coltab[][4]; */ +/* short *deltab; */ +{ + short r,g,b,lr,lg,lb,dr,dg,db,col,fout,type,step; + int i; + uchar *rect; + + /* + b = 0000 xxxx + g = 0001 xxxx + r = 0010 xxxx + cmap >= 48 + */ + + for (step = 0 ; step < 2 ; step ++){ + rect = (uchar *) ibuf->rect; + rect += 4*step; + i = ((ibuf->x * ibuf->y) + 2 - step - 1) / 2; + + lb = coltab[0][1]; + lg = coltab[0][2]; + lr = coltab[0][3]; + type = col = 0; + + for ( ;i>0;i--){ + b = rect[2] >> 4; + g = rect[1] >> 4; + r = rect[0] >> 4; + + if ((b-lb) | (g-lg) | (r-lr)){ + col = ((b<<8) + (g<<4) + r) << 1; + fout = deltab[col + 1]; + col = deltab[col]; + type = 0; + dr = quadr[lr-r] ; + dg = quadr[lg-g] ; + db = quadr[lb-b]; + + if ((dr+dg)<=fout) { + fout = dr+dg ; + type = 1; + } + if ((dg+db)<=fout) { + fout = dg+db; + type = 2; + } + if ((dr+db)<=fout) { + fout = dr+db; + type = 4; + } + + switch(type){ + case 1: + lb = b ; + col = b; + break; + case 4: + lg = g ; + col = g+16; + break; + case 2: + lr = r ; + col = r + 32; + break; + default: + /*printf("%04x %5d %5d ", (b<<8) + (g<<4) + r, col, fout);*/ + + lb = coltab[col][1]; + lg = coltab[col][2]; + lr = coltab[col][3]; + /*printf("%01x%01x%01x %01x%01x%01x\n", b, g, r, lb, lg, lr);*/ + col += 48; + } + } + rect[3] = col; + rect += 8; + } + } +} + +static short dec_hamx(struct ImBuf * ibuf, unsigned char *body, int cmap[]) +/* struct ImBuf * ibuf; */ +/* uchar *body; */ +/* int cmap[]; */ +{ + int todo,i; + int j,step,col; + unsigned int *rect; + + for (step = 0 ; step < 2 ; step ++){ + rect = ibuf->rect; + rect += step; + todo = (ibuf->x * ibuf->y + 2 - step - 1) / 2; + col = cmap[0]; + while (todo>0){ + i = *body++; + + if (i & 128){ /* fill */ + + i = 257-i; + todo -= i; + j = *(body++); + + col = ((col & hamx_array[j]) | hamx_array[j + 256]); + + do{ + *rect = col; + rect += 2; + }while (--i); + } else{ /* copy */ + i++; + todo-=i; + + do{ + j = *(body++); + *rect = col = ((col & hamx_array[j]) | hamx_array[j + 256]); + rect += 2; + }while (--i); + } + } + if (todo) return (0); + } + return(1); +} + + +struct ImBuf *imb_loadanim(int *iffmem, int flags) +{ + int chunk, totlen, len, *mem, cmaplen = 0; + unsigned int *cmap; + uchar *body = 0; + struct Adat adat; + struct ImBuf *ibuf=0; + static int is_flipped = FALSE; + + mem=iffmem; + if (GET_ID(mem) != FORM) return (0); + if (GET_ID(mem + 2) != ANIM) return (0); + totlen= (GET_BIG_LONG(mem + 1) + 1) & ~1; + mem += 3; + totlen -= 4; + adat.w = 0; + adat.xorig = 0; + adat.yorig = 0; + adat.gamma = adat_gamma; + adat.distort = adat_distort; + + while(totlen > 0){ + chunk = GET_ID(mem); + len = (GET_BIG_LONG(mem + 1) + 1) & ~1; + mem += 2; + + totlen -= len+8; + switch (chunk){ + case ADAT: + if (len > sizeof(struct Adat)){ + memcpy(&adat,mem,sizeof(struct Adat)); + } else{ + memcpy(&adat,mem,len); + } + adat.w = BIG_SHORT(adat.w); + adat.h = BIG_SHORT(adat.h); + adat.type = BIG_SHORT(adat.type); + adat.xorig = BIG_SHORT(adat.xorig); + adat.yorig = BIG_SHORT(adat.yorig); + break; + case CMAP: + cmap = (unsigned int *) mem; + cmaplen = len; + break; + case BODY: + body = (uchar *) mem; + break; + } + mem = (int *)((uchar *)mem +len); + } + + if (body == 0) return (0); + if (adat.w == 0) return (0); + + adat_gamma = adat.gamma; + adat_distort = adat.distort; + + if (flags & IB_test) ibuf=IMB_allocImBuf(adat.w, adat.h, 24, 0, 0); + else ibuf=IMB_allocImBuf(adat.w, adat.h, 24, IB_rect, 0); + if (ibuf==0) return (0); + + ibuf->ftype = (Anim | adat.type); + ibuf->xorig = adat.xorig; + ibuf->yorig = adat.yorig; + ibuf->flags = flags; + + if (cmaplen){ + ibuf->cmap = malloc(cmaplen); + memcpy(ibuf->cmap, cmap, cmaplen); + ibuf->maxcol = cmaplen >> 2; + } + + if (flags & IB_test){ + if (flags & IB_freem) free(iffmem); + return(ibuf); + } + + switch (adat.type){ + case HAMX: + if (flags & IB_rect){ + if (!is_flipped) { + int i; + unsigned int * t; + t = (unsigned int *) hamx_array_char; + for (i = 0; i < sizeof(hamx_array_char) / sizeof(int) ; i++) { + t[i] = SWAP_LONG(t[i]); + } + + t = (unsigned int *) cmap_hamx; + + for (i = 0; i < sizeof(cmap_hamx) / sizeof(int) ; i++) { + t[i] = SWAP_LONG(t[i]); + } + + is_flipped= TRUE; + } + + if (dec_hamx(ibuf,body,(int*) cmap_hamx) == 0){ + IMB_freeImBuf(ibuf); + ibuf = 0; + } + if (flags & IB_ttob) IMB_flipy(ibuf); + } + break; + default: + IMB_freeImBuf(ibuf); + ibuf = 0; + } + + if (flags & IB_freem) free(iffmem); + + return (ibuf); +} + + +static unsigned char *makebody_anim(int bytes, + unsigned char *buf, + unsigned char *rect) +/* register uchar *buf; */ +/* register uchar *rect; */ +/* int bytes; */ +{ + register uchar last,this; + register int copy; + register uchar *rectstart,*temp; + + bytes--; + rectstart = rect; + last = *rect++; + this = *rect++; + copy = last^this; + while (bytes>0){ + if (copy){ + do{ + last = this; + this = *rect++; + if (last == this){ + if (this == rect[-3]){ /* drie dezelfde? */ + bytes --; /* bytes goed zetten */ + break; + } + } + }while (--bytes != 0); + + copy = rect-rectstart; + copy --; + if (bytes) copy -= 2; + + temp = rect; + rect = rectstart; + + while (copy){ + last = copy; + if (copy>MAXDAT) last = MAXDAT; + copy -= last; + *buf++ = last-1; + do{ + *buf++ = *rect++; + }while(--last != 0); + } + rectstart = rect; + rect = temp; + last = this; + + copy = FALSE; + } else { + while (*rect++ == this){ /* zoek naar eerste afwijkende byte */ + if (--bytes == 0) break; /* of einde regel */ + } + rect --; + copy = rect-rectstart; + rectstart = rect; + bytes --; + this = *rect++; + + while (copy){ + if (copy>MAXRUN){ + *buf++ = -(MAXRUN-1); + *buf++ = last; + copy -= MAXRUN; + } else { + *buf++ = -(copy-1); + *buf++ = last; + break; + } + } + copy=TRUE; + } + } + return (buf); +} + + +short imb_enc_anim(struct ImBuf *ibuf, int file) +/* struct ImBuf *ibuf; */ +/* int file; */ +{ + int step, steps, size, i, skip; + uchar *buf1, *crect, *_buf1, *_buf2, *bufend; + short ok = TRUE; + + if (ibuf == 0) return (0); + if (file < 0 ) return (0); + if (ibuf->rect == 0) return(0); + + /* dither toevoegen */ + + switch(ibuf->ftype){ + case AN_hamx: + ibuf->cmap = (unsigned int *) cmap_hamx; + ibuf->mincol = 0; + ibuf->maxcol = sizeof(cmap_hamx) / 4; + imb_converttoham(ibuf); + steps = 2; + break; + } + + size = ((ibuf->x + 1)* (ibuf->y + 1)) / steps + 1024; + if ((_buf1 = malloc(size)) == 0) return(0); + if ((_buf2 = malloc(size)) == 0){ + free(_buf1); + return(0); + } + + skip = 4 * steps; + for (step = 0 ; step < steps ; step ++){ + crect = (uchar *) ibuf->rect; + crect += 4 * step; + size = (ibuf->x * ibuf->y + steps - step - 1) / steps; + buf1 = _buf1; + if ((ibuf->ftype == AN_hamx) || (ibuf->ftype == AN_yuvx)){ + crect += 3; + for (i = size ; i>0 ; i--){ + *(buf1 ++) = *crect; + crect += skip; + } + } else{ + for (i = size ; i>0 ; i--){ + *(buf1 ++) = crect[1] + (crect[2] >> 2) + (crect[3] >> 5); + crect += skip; + } + } + bufend = makebody_anim(size,_buf2,_buf1); + if (bufend == 0){ + ok = FALSE; + break; + } + size = bufend - _buf2; + if (write(file, _buf2, size) != size){ + ok = FALSE; + break; + } + } + free(_buf1); + free(_buf2); + return (ok); +} diff --git a/source/blender/imbuf/intern/iff.c b/source/blender/imbuf/intern/iff.c new file mode 100644 index 00000000000..640eb253c26 --- /dev/null +++ b/source/blender/imbuf/intern/iff.c @@ -0,0 +1,225 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * iff.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" + +#include "IMB_iff.h" + +unsigned short imb_start_iff(struct ImBuf *ibuf, int file) +{ + unsigned int *point, size, *buf; + + if ((point=buf=(unsigned int *)malloc(32768))==0) return FALSE; + + *point++ = FORM; /* FORMxxxxILBM in buffer */ + *point++ = 0; + + if (IS_amiga(ibuf)){ + struct BitMapHeader *bmhd; + + *point++ = ILBM; + *point++ = CAMG; + *point++ = 4; + *point++ = (ibuf->ftype & 0xffff); + + *point++=BMHD; + *point++=sizeof(struct BitMapHeader); + + bmhd=(struct BitMapHeader *)point; /* bmhd wijst naar plek waar bmhd moet komen */ + point=(unsigned int *)((char *)point+sizeof(struct BitMapHeader)); /* pointer alvast verder zetten */ + + bmhd->w=ibuf->x; + bmhd->h=ibuf->y; + bmhd->pageWidth=ibuf->x; + bmhd->pageHeight=ibuf->y; + bmhd->x=0; + bmhd->y=0; + bmhd->nPlanes=ibuf->depth; + bmhd->masking=0; + if (ibuf->flags & IB_vert){ + bmhd->compression=2; + } + else{ + bmhd->compression=1; + } + bmhd->pad1=0; + bmhd->transparentColor=0; + bmhd->xAspect=1; + bmhd->yAspect=1; + } else if (IS_anim(ibuf)){ + struct Adat *adat; + extern float adat_gamma; + extern float adat_distort; + + *point++ = ANIM; + *point++ = ADAT; + *point++ = BIG_LONG(sizeof(struct Adat)); + + adat = (struct Adat *)point; + point = (unsigned int *)((char *)point+sizeof(struct Adat)); /* pointer alvast verder zetten */ + + adat->w = BIG_SHORT(ibuf->x); + adat->h = BIG_SHORT(ibuf->y); + + adat->type = BIG_SHORT(ibuf->ftype); + adat->xorig = BIG_SHORT(ibuf->xorig); + adat->yorig = BIG_SHORT(ibuf->yorig); + adat->pad = 0; + adat->gamma = adat_gamma; + adat->distort = adat_distort; + } + + size=((uchar *)point-(uchar *)buf); + if (write(file,buf,size)!=size){ + free(buf); + return (FALSE); + } + + if (ibuf->cmap){ + if (IS_anim(ibuf)){ + size = ibuf->maxcol * sizeof(int); + buf[0] = CMAP; + buf[1] = BIG_LONG(size); + if (write(file,buf,8) != 8){ + free(buf); + return (FALSE); + } + if (write(file,ibuf->cmap,size) != size){ + free(buf); + return (FALSE); + } + } else{ + uchar *cpoint,*cols; + unsigned int i,bits; + + point = buf; + if (IS_amiga(ibuf)){ + *(point++) = CMAP; + *(point++) = BIG_LONG(3*ibuf->maxcol); + } + + cpoint = (uchar *) point; + cols = (uchar *)ibuf->cmap; + if ((ibuf->cbits > 0) && (ibuf->cbits < 8)){ + bits = ~((1 << (8-ibuf->cbits)) - 1); + } else bits = -1; + + if (IS_ham(ibuf)) bits = -1; + + for (i=0 ; i<ibuf->maxcol ; i++){ + *(cpoint++) = cols[0] & bits; + *(cpoint++) = cols[1] & bits; + *(cpoint++) = cols[2] & bits; + cols += 4; + } + if (ibuf->maxcol & 1) *(cpoint++)=0; + + size=(cpoint-(uchar *)buf); + if (write(file,buf,size)!=size){ + free(buf); + return (FALSE); + } + } + } + + if (IS_amiga(ibuf)) buf[0] = BODY; + if (IS_anim(ibuf)) buf[0] = BODY; + buf[1]=0; + + if (write(file,buf,8)!=8){ + free(buf); + return(FALSE); + } + + free(buf); + return (TRUE); +} + + +unsigned short imb_update_iff(int file, int code) +{ + int buf[2], filelen, skip; + uchar nop; + + if (file<=0) return (FALSE); + + filelen = BLI_filesize(file)-8; /* filelengte berekenen */ + + lseek(file,0L,2); /* seek end */ + + if (filelen & 1){ /* lengte even maken */ + switch(code){ + case BODY: + nop = IFFNOP; + break; + } + if (write(file,&nop,1)!=1) return (FALSE); + filelen++; + } + lseek(file,4L,0); + + buf[0] = BIG_LONG(filelen); + + if (write(file, buf, 4) != 4) return (FALSE); + if (code == 0) return (TRUE); + + filelen-=4; + lseek(file,4L,1); + + while (filelen>0){ /* zoek BODY op */ + read(file, buf, 8); + filelen -= 8; + if (buf[0] == code) break; + + skip = BIG_LONG(buf[1]) + 1 & ~1; + filelen -= skip; + lseek(file, skip, 1); + } + if (filelen <= 0) { + printf("update_iff: couldn't find chunk\n"); + return (FALSE); + } + + lseek(file, -4L, 1); + + buf[0] = BIG_LONG(filelen); + + if (write(file, buf, 4)!=4) return (FALSE); + + return (TRUE); +} diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c new file mode 100644 index 00000000000..dcdd0692fc4 --- /dev/null +++ b/source/blender/imbuf/intern/imageprocess.c @@ -0,0 +1,59 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * This file was moved here from the src/ directory. It is meant to + * deal with endianness. It resided in a general blending lib. The + * other functions were only used during rendering. This single + * function remained. It should probably move to imbuf/intern/util.c, + * but we'll keep it here for the time being. (nzc)*/ + +/* imageprocess.c MIXED MODEL + * + * april 95 + * + * $Id$ + */ + +#include "IMB_imbuf.h" + +/* Only this one is used liberally here, and in imbuf */ +void IMB_convert_rgba_to_abgr(int size, unsigned int *rect) +{ + char *cp= (char *)rect, rt; + + while(size-- > 0) { + rt= cp[0]; + cp[0]= cp[3]; + cp[3]= rt; + rt= cp[1]; + cp[1]= cp[2]; + cp[2]= rt; + cp+= 4; + } +} diff --git a/source/blender/imbuf/intern/imbuf.h b/source/blender/imbuf/intern/imbuf.h new file mode 100644 index 00000000000..d22d408ddaa --- /dev/null +++ b/source/blender/imbuf/intern/imbuf.h @@ -0,0 +1,190 @@ +/** + * imbuf.h (mar-2001 nzc) + * + * This header might have to become external... + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef IMBUF_H +#define IMBUF_H + +#include <stdlib.h> +#include <sys/types.h> +#include <stdio.h> + +#ifndef WIN32 +#include <unistd.h> +#endif + +#include <fcntl.h> +#include <sys/stat.h> +#include <string.h> +#include <math.h> + +#if !defined(__FreeBSD__) && !defined(__APPLE__) + +/* #include <malloc.h> */ /* _should_ be in stdlib */ + +#endif + +#ifndef WIN32 +#include <sys/mman.h> +#endif + +#if !defined(WIN32) && !defined(__BeOS) +#define O_BINARY 0 +#endif + +#define SWAP_SHORT(x) (((x & 0xff) << 8) | ((x >> 8) & 0xff)) +#define SWAP_LONG(x) (((x) << 24) | (((x) & 0xff00) << 8) | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff)) + +#define ENDIAN_NOP(x) (x) + +#if defined(__sgi) || defined(__sparc) || defined (__PPC__) || defined (__APPLE__) +#define LITTLE_SHORT SWAP_SHORT +#define LITTLE_LONG SWAP_LONG +#define BIG_SHORT ENDIAN_NOP +#define BIG_LONG ENDIAN_NOP +#else +#define LITTLE_SHORT ENDIAN_NOP +#define LITTLE_LONG ENDIAN_NOP +#define BIG_SHORT SWAP_SHORT +#define BIG_LONG SWAP_LONG +#endif + +#define malloc(x) MEM_mallocN(x, __FILE__) +#define free(x) MEM_freeN(x) +#define calloc(x,y) MEM_callocN((x)*(y), __FILE__) +#define freelist(x) BLI_freelistN(x) + +/* +bindkey -r f1,'cc -O -c imbuf.c\n' + +bindkeyo -r f1,'make paint \n' +bindkeyo -r f2,'paint /usr/4Dgifts/iristools/images/max5.rgb \n' + +bindkey -r f1,'cc paint.c imbuf.c -lgl_s -lm -lfm_s -g -o paint\n' +bindkey -r f2,'/usr/people/bin/compres /usr/people/pics/0600\n' + +compileren met: + +lc -Lm -f8 -dAMIGA imbuf +*/ + +#ifdef SHLIB +void *(*ib_calloc)(); +#define calloc(x,y) ib_calloc((x),(y)) +void *(*ib_malloc)(); +#define malloc(x) ib_malloc(x) +void (*ib_free)(); +#define free(x) ib_free(x) +void (*ib_memcpy)(); +#define memcpy(x,y,z) ib_memcpy((x),(y),(z)) +int (*ib_abs)(); +#define abs(x) ib_abs(x) +void (*ib_fprin_tf)(); +#define fprintf ib_fprin_tf +int (*ib_sprin_tf)(); +#define sprintf ib_sprin_tf +void (*ib_prin_tf)(); +#define printf ib_prin_tf +int (*ib_lseek)(); +#define lseek(x,y,z) ib_lseek((x),(y),(z)) +void *(*ib_mmap)(); +#define mmap(u,v,w,x,y,z) ib_mmap((u),(v),(w),(x),(y),(z)) +int (*ib_munmap)(); +#define munmap(x,y) ib_munmap((x),(y)) +int (*ib_open)(); +#define open(x,y) ib_open((x),(y)) +void (*ib_close)(); +#define close(x) ib_close(x) +int (*ib_write)(); +#define write(x,y,z) ib_write((x),(y),(z)) +int (*ib_read)(); +#define read(x,y,z) ib_read((x),(y),(z)) +int (*ib_fchmod)(); +#define fchmod(x,y) ib_fchmod((x),(y)) +int (*ib_remove)(); +#define remove(x) ib_remove(x) +size_t (*ib_strlen)(); +#define strlen(x) ib_strlen(x) +int (*ib_isdigit)(); +#define isdigit(x) ib_isdigit(x) +char *(*ib_strcpy)(); +#define strcpy(x,y) ib_strcpy((x),(y)) +int (*ib_atoi)(); +#define atoi(x) ib_atoi(x) +char *(*ib_strcat)(); +#define strcat(x,y) ib_strcat((x),(y)) +int (*ib_stat)(); +/* #define stat(x,y) ib_stat((x),(y)) */ +FILE *ib_iob; +#define _iob ib_iob + +#else + +#define ib_stat stat + +#endif /* SHLIB */ + + +#define WIDTHB(x) (((x+15)>>4)<<1) + +extern unsigned short *quadr; +extern float dyuvrgb[4][4]; +extern float rgbdyuv[4][4]; + + +typedef struct Adat +{ + unsigned short w, h; + unsigned short type; + unsigned short xorig, yorig; + unsigned short pad; + float gamma; + float distort; +}Adat; + +struct BitMapHeader +{ + unsigned short w, h; /* in pixels */ + unsigned short x, y; + char nPlanes; + char masking; + char compression; + char pad1; + unsigned short transparentColor; + char xAspect, yAspect; + short pageWidth, pageHeight; +}; + +#endif /* IMBUF_H */ diff --git a/source/blender/imbuf/intern/imbuf_patch.h b/source/blender/imbuf/intern/imbuf_patch.h new file mode 100644 index 00000000000..9dbdc55969c --- /dev/null +++ b/source/blender/imbuf/intern/imbuf_patch.h @@ -0,0 +1,114 @@ +/** + * imbuf_patch.h + * + * These are some definitions to make imbuf more independent from the + * rest of the blender code. Most of these are dirty and should not + * really exist. + * + * $Id$ * + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef IMBUF_PATCH_H +#define IMBUF_PATCH_H + +/* most of imbuf uses this aloc, and it will disappear soon + * (hopefully) (25-10-2001 nzc) */ +#include "MEM_guardedalloc.h" + +struct ImBuf; + +/* originally, these were defines ... */ +typedef unsigned char uchar; + +/* should not be used at all */ +#define TRUE 1 +#define FALSE 0 + +/* Endianness: flip the byte order. It's strange that this is needed.. + * After all, there is an internal endian.{c,h}... */ +#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +#define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#else +#define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) +#endif + +/* These defines loop back to the internal Blender memory management + * system, implemented in blenlib. */ +#define NEW(x) (x*)MEM_mallocN(sizeof(x),# x) +#define mallocstruct(x,y) (x*)malloc((y)* sizeof(x)) +#define callocstruct(x,y) (x*)calloc((y), sizeof(x)) + +/* These vars are used thoughout the image buffer for conversions. */ +extern float rgbyuv[4][4]; +extern float yuvrgb[4][4]; +extern float rgbbeta[4][4]; + +/* This one helps debugging. */ +extern int IB_verbose; + +/* These ID's are used for checking memory blocks. See blenlib for + * more details. This set is only used in the imbuf internally. */ + +#define CAT MAKE_ID('C','A','T',' ') +#define FORM MAKE_ID('F','O','R','M') +#define ILBM MAKE_ID('I','L','B','M') +#define BMHD MAKE_ID('B','M','H','D') +#define CMAP MAKE_ID('C','M','A','P') +#define CAMG MAKE_ID('C','A','M','G') +#define BODY MAKE_ID('B','O','D','Y') + +#define ANIM MAKE_ID('A','N','I','M') +#define ADAT MAKE_ID('A','D','A','T') +#define CODE MAKE_ID('C','O','D','E') +#define ANHD MAKE_ID('A','N','H','D') +#define DLTA MAKE_ID('D','L','T','A') +#define BLCK MAKE_ID('B','L','C','K') + +#define MAXRUN 126 +#define MAXDAT 126 +#define IFFNOP 128 + +#define camg ftype + +#define LI_rect IB_rect +#define LI_planes IB_planes +#define LI_kcmap IB_cmap +#define LI_cmap IB_cmap +#define LI_freem IB_freem +#define LI_test IB_test + +#define SI_rect IB_rect +#define SI_planes IB_planes +#define SI_kcmap IB_cmap +#define SI_cmap IB_cmap +#define SI_vert IB_vert + +#endif + diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c new file mode 100644 index 00000000000..72a9a76d044 --- /dev/null +++ b/source/blender/imbuf/intern/iris.c @@ -0,0 +1,727 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * iris.c + * + * $Id$ + */ + +#include <string.h> +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_iris.h" + + +typedef struct { + unsigned short imagic; /* stuff saved on disk . . */ + unsigned short type; + unsigned short dim; + unsigned short xsize; + unsigned short ysize; + unsigned short zsize; + unsigned int min; + unsigned int max; + unsigned int wastebytes; + char name[80]; + unsigned int colormap; + + int file; /* stuff used in core only */ + unsigned short flags; + short dorev; + short x; + short y; + short z; + short cnt; + unsigned short *ptr; + unsigned short *base; + unsigned short *tmpbuf; + unsigned int offset; + unsigned int rleend; /* for rle images */ + unsigned int *rowstart; /* for rle images */ + int *rowsize; /* for rle images */ +} IMAGE; + +#define RINTLUM (79) +#define GINTLUM (156) +#define BINTLUM (21) + +#define ILUM(r,g,b) ((int)(RINTLUM*(r)+GINTLUM*(g)+BINTLUM*(b))>>8) + +#define OFFSET_R 0 /* this is byte order dependent */ +#define OFFSET_G 1 +#define OFFSET_B 2 +#define OFFSET_A 3 + +#define CHANOFFSET(z) (3-(z)) /* this is byte order dependent */ + +#define TYPEMASK 0xff00 +#define BPPMASK 0x00ff +#define ITYPE_VERBATIM 0x0000 +#define ITYPE_RLE 0x0100 +#define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE) +#define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM) +#define BPP(type) ((type) & BPPMASK) +#define RLE(bpp) (ITYPE_RLE | (bpp)) +#define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp)) +#define IBUFSIZE(pixels) ((pixels+(pixels>>6))<<2) +#define RLE_NOP 0x00 + +/* funcs */ +static void readheader(FILE *inf, IMAGE *image); +static int writeheader(FILE *outf, IMAGE *image); + +static unsigned short getshort(FILE *inf); +static unsigned int getlong(FILE *inf); +static void putshort(FILE *outf, unsigned short val); +static int putlong(FILE *outf, unsigned int val); +static int writetab(FILE *outf, unsigned int *tab, int len); +static void readtab(FILE *inf, unsigned int *tab, int len); + +static void expandrow(unsigned char *optr, unsigned char *iptr, int z); +static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n); +static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt); +static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n); + +/* not used... */ +/* static void copybw(int *lptr, int n); */ +/* static void setalpha(unsigned char *lptr, int n); */ + +/* + * byte order independent read/write of shorts and ints. + * + */ + +static uchar * file_data; +static int file_offset; + +static unsigned short getshort(FILE *inf) +/* FILE *inf; */ +{ + unsigned char * buf; + + buf = file_data + file_offset; + file_offset += 2; + + return (buf[0]<<8)+(buf[1]<<0); +} + +static unsigned int getlong(FILE *inf) +/* FILE *inf; */ +{ + unsigned char * buf; + + buf = file_data + file_offset; + file_offset += 4; + + return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0); +} + +static void putshort(FILE *outf, unsigned short val) +/* FILE *outf; */ +/* unsigned short val; */ +{ + unsigned char buf[2]; + + buf[0] = (val>>8); + buf[1] = (val>>0); + fwrite(buf,2,1,outf); +} + +static int putlong(FILE *outf, unsigned int val) +/* FILE *outf; */ +/* unsigned int val; */ +{ + unsigned char buf[4]; + + buf[0] = (val>>24); + buf[1] = (val>>16); + buf[2] = (val>>8); + buf[3] = (val>>0); + return fwrite(buf,4,1,outf); +} + +static void readheader(FILE *inf, IMAGE *image) +/* FILE *inf; */ +/* IMAGE *image; */ +{ + memset(image, 0, sizeof(IMAGE)); + image->imagic = getshort(inf); + image->type = getshort(inf); + image->dim = getshort(inf); + image->xsize = getshort(inf); + image->ysize = getshort(inf); + image->zsize = getshort(inf); +} + +static int writeheader(FILE *outf, IMAGE *image) +/* FILE *outf; */ +/* IMAGE *image; */ +{ + IMAGE t; + + memset(&t, 0, sizeof(IMAGE)); + fwrite(&t,sizeof(IMAGE),1,outf); + fseek(outf,0,SEEK_SET); + putshort(outf,image->imagic); + putshort(outf,image->type); + putshort(outf,image->dim); + putshort(outf,image->xsize); + putshort(outf,image->ysize); + putshort(outf,image->zsize); + putlong(outf,image->min); + putlong(outf,image->max); + putlong(outf,0); + return fwrite("no name",8,1,outf); +} + +static int writetab(FILE *outf, unsigned int *tab, int len) +/* FILE *outf; */ +/* unsigned int *tab; */ +/* int len; */ +{ + int r; + + while(len) { + r = putlong(outf,*tab++); + len -= 4; + } + return r; +} + +static void readtab(FILE *inf, unsigned int *tab, int len) +/* FILE *inf; */ +/* unsigned int *tab; */ +/* int len; */ +{ + while(len) { + *tab++ = getlong(inf); + len -= 4; + } +} + +static void test_endian_zbuf(struct ImBuf *ibuf) +{ + int len; + int *zval; + + if( BIG_LONG(1) == 1 ) return; + if(ibuf->zbuf==0) return; + + len= ibuf->x*ibuf->y; + zval= ibuf->zbuf; + + while(len--) { + zval[0]= BIG_LONG(zval[0]); + zval++; + } +} + + +/* + * longimagedata - + * read in a B/W RGB or RGBA iris image file and return a + * pointer to an array of ints. + * + */ + +struct ImBuf *imb_loadiris(unsigned char *mem, int flags) +{ + unsigned int *base, *lptr; + unsigned int *zbase, *zptr; + unsigned char *rledat; + int *starttab, *lengthtab; + FILE *inf; + IMAGE image; + int x, y, z, tablen; + int xsize, ysize, zsize; + int bpp, rle, cur, badorder; + ImBuf * ibuf; + uchar * rect; + + /*printf("new iris\n");*/ + + file_data = mem; + file_offset = 0; + + readheader(inf, &image); + if(image.imagic != IMAGIC) { + fprintf(stderr,"longimagedata: bad magic number in image file\n"); + return(0); + } + + rle = ISRLE(image.type); + bpp = BPP(image.type); + if(bpp != 1 ) { + fprintf(stderr,"longimagedata: image must have 1 byte per pix chan\n"); + return(0); + } + + xsize = image.xsize; + ysize = image.ysize; + zsize = image.zsize; + + if (flags & IB_test) { + ibuf = IMB_allocImBuf(image.xsize, image.ysize, 8 * image.zsize, 0, 0); + if (ibuf) ibuf->ftype = IMAGIC; + return(ibuf); + } + + if (rle) { + tablen = ysize*zsize*sizeof(int); + starttab = (int *)malloc(tablen); + lengthtab = (int *)malloc(tablen); + file_offset = 512; + + readtab(inf,starttab,tablen); + readtab(inf,lengthtab,tablen); + + /* check data order */ + cur = 0; + badorder = 0; + for (y = 0; y<ysize; y++) { + for (z = 0; z<zsize; z++) { + if (starttab[y+z*ysize]<cur) { + badorder = 1; + break; + } + cur = starttab[y+z*ysize]; + } + if(badorder) + break; + } + + ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0); + if (ibuf->depth > 32) ibuf->depth = 32; + base = ibuf->rect; + zbase = (unsigned int *)ibuf->zbuf; + + if (badorder) { + for(z=0; z<zsize; z++) { + lptr = base; + for(y=0; y<ysize; y++) { + file_offset = starttab[y+z*ysize]; + + rledat = file_data + file_offset; + file_offset += lengthtab[y+z*ysize]; + + expandrow(lptr, rledat, 3-z); + lptr += xsize; + } + } + } + else { + lptr = base; + zptr = zbase; + for(y=0; y<ysize; y++) { + + for(z=0; z<zsize; z++) { + + file_offset = starttab[y+z*ysize]; + + rledat = file_data + file_offset; + file_offset += lengthtab[y+z*ysize]; + + if(z<4) expandrow(lptr, rledat, 3-z); + else if(z<8) expandrow(zptr, rledat, 7-z); + } + lptr += xsize; + zptr += xsize; + } + } + + free(starttab); + free(lengthtab); + } + else { + + ibuf = IMB_allocImBuf(xsize, ysize, 8 * zsize, IB_rect, 0); + if (ibuf->depth > 32) ibuf->depth = 32; + + base = ibuf->rect; + zbase = (unsigned int *)ibuf->zbuf; + + file_offset = 512; + rledat = file_data + file_offset; + + for(z = 0; z < zsize; z++) { + + if(z<4) lptr = base; + else if(z<8) lptr= zbase; + + for(y = 0; y < ysize; y++) { + + interleaverow(lptr, rledat, 3-z, xsize); + rledat += xsize; + + lptr += xsize; + } + } + } + + if (image.zsize == 1){ + rect = (uchar *) ibuf->rect; + for (x = ibuf->x * ibuf->y; x > 0; x--) { + rect[0] = 255; + rect[1] = rect[2] = rect[3]; + rect += 4; + } + } else if (image.zsize == 3){ + /* alpha toevoegen */ + rect = (uchar *) ibuf->rect; + for (x = ibuf->x * ibuf->y; x > 0; x--) { + rect[0] = 255; + rect += 4; + } + } + + ibuf->ftype = IMAGIC; + if (flags & IB_ttob) IMB_flipy(ibuf); + + test_endian_zbuf(ibuf); + + if (ibuf) { + if (ibuf->rect) + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + } + + return(ibuf); +} + +/* static utility functions for longimagedata */ + +static void interleaverow(unsigned char *lptr, unsigned char *cptr, int z, int n) +/* unsigned char *lptr, *cptr; */ +/* int z, n; */ +{ + lptr += z; + while(n--) { + *lptr = *cptr++; + lptr += 4; + } +} + +/* not used? */ +/*static void copybw(int *lptr, int n) */ +/* int *lptr; */ +/* int n; */ +/*{ + while(n>=8) { + lptr[0] = 0xff000000+(0x010101*(lptr[0]&0xff)); + lptr[1] = 0xff000000+(0x010101*(lptr[1]&0xff)); + lptr[2] = 0xff000000+(0x010101*(lptr[2]&0xff)); + lptr[3] = 0xff000000+(0x010101*(lptr[3]&0xff)); + lptr[4] = 0xff000000+(0x010101*(lptr[4]&0xff)); + lptr[5] = 0xff000000+(0x010101*(lptr[5]&0xff)); + lptr[6] = 0xff000000+(0x010101*(lptr[6]&0xff)); + lptr[7] = 0xff000000+(0x010101*(lptr[7]&0xff)); + lptr += 8; + n-=8; + } + while(n--) { + *lptr = 0xff000000+(0x010101*(*lptr&0xff)); + lptr++; + } +} +*/ + +/* not used ? */ +/*static void setalpha(unsigned char *lptr, int n)*/ +/* unsigned char *lptr; */ +/*{ + while(n>=8) { + lptr[0*4] = 0xff; + lptr[1*4] = 0xff; + lptr[2*4] = 0xff; + lptr[3*4] = 0xff; + lptr[4*4] = 0xff; + lptr[5*4] = 0xff; + lptr[6*4] = 0xff; + lptr[7*4] = 0xff; + lptr += 4*8; + n -= 8; + } + while(n--) { + *lptr = 0xff; + lptr += 4; + } +} +*/ + +static void expandrow(unsigned char *optr, unsigned char *iptr, int z) +/* unsigned char *optr, *iptr; */ +/* int z; */ +{ + unsigned char pixel, count; + + optr += z; + while(1) { + pixel = *iptr++; + if ( !(count = (pixel & 0x7f)) ) + return; + if(pixel & 0x80) { + while(count>=8) { + optr[0*4] = iptr[0]; + optr[1*4] = iptr[1]; + optr[2*4] = iptr[2]; + optr[3*4] = iptr[3]; + optr[4*4] = iptr[4]; + optr[5*4] = iptr[5]; + optr[6*4] = iptr[6]; + optr[7*4] = iptr[7]; + optr += 8*4; + iptr += 8; + count -= 8; + } + while(count--) { + *optr = *iptr++; + optr+=4; + } + } else { + pixel = *iptr++; + while(count>=8) { + optr[0*4] = pixel; + optr[1*4] = pixel; + optr[2*4] = pixel; + optr[3*4] = pixel; + optr[4*4] = pixel; + optr[5*4] = pixel; + optr[6*4] = pixel; + optr[7*4] = pixel; + optr += 8*4; + count -= 8; + } + while(count--) { + *optr = pixel; + optr+=4; + } + } + } +} + +/* + * output_iris - + * copy an array of ints to an iris image file. Each int + * represents one pixel. xsize and ysize specify the dimensions of + * the pixel array. zsize specifies what kind of image file to + * write out. if zsize is 1, the luminance of the pixels are + * calculated, and a sinlge channel black and white image is saved. + * If zsize is 3, an RGB image file is saved. If zsize is 4, an + * RGBA image file is saved. + * + * Added: zbuf write + */ + +static int output_iris(unsigned int *lptr, int xsize, int ysize, int zsize, int file, int *zptr) +{ + FILE *outf; + IMAGE *image; + int tablen, y, z, pos, len; + int *starttab, *lengthtab; + unsigned char *rlebuf; + unsigned int *lumbuf; + int rlebuflen, goodwrite; + + goodwrite = 1; + outf = fdopen(file, "wb"); + + if(!outf) { + perror("fdopen"); + fprintf(stderr,"output_iris: can't open output file\n"); + return 0; + } + tablen = ysize*zsize*sizeof(int); + + image = (IMAGE *)malloc(sizeof(IMAGE)); + starttab = (int *)malloc(tablen); + lengthtab = (int *)malloc(tablen); + rlebuflen = 1.05*xsize+10; + rlebuf = (unsigned char *)malloc(rlebuflen); + lumbuf = (unsigned int *)malloc(xsize*sizeof(int)); + + memset(image, 0, sizeof(IMAGE)); + image->imagic = IMAGIC; + image->type = RLE(1); + if(zsize>1) + image->dim = 3; + else + image->dim = 2; + image->xsize = xsize; + image->ysize = ysize; + image->zsize = zsize; + image->min = 0; + image->max = 255; + goodwrite *= writeheader(outf,image); + fseek(outf,512+2*tablen,SEEK_SET); + pos = 512+2*tablen; + + for (y = 0; y < ysize; y++) { + for (z = 0; z < zsize; z++) { + + if (zsize == 1) { + lumrow(lptr,lumbuf,xsize); + len = compressrow(lumbuf,rlebuf,CHANOFFSET(z),xsize); + } + else { + if(z<4) { + len = compressrow(lptr, rlebuf,CHANOFFSET(z),xsize); + } + else if(z<8 && zptr) { + len = compressrow(zptr, rlebuf,CHANOFFSET(z-4),xsize); + } + } + if(len>rlebuflen) { + fprintf(stderr,"output_iris: rlebuf is too small - bad poop\n"); + exit(1); + } + goodwrite *= fwrite(rlebuf, len, 1, outf); + starttab[y+z*ysize] = pos; + lengthtab[y+z*ysize] = len; + pos += len; + } + lptr += xsize; + if(zptr) zptr += xsize; + } + + fseek(outf,512,SEEK_SET); + goodwrite *= writetab(outf,starttab,tablen); + goodwrite *= writetab(outf,lengthtab,tablen); + free(image); + free(starttab); + free(lengthtab); + free(rlebuf); + free(lumbuf); + fclose(outf); + if(goodwrite) + return 1; + else { + fprintf(stderr,"output_iris: not enough space for image!!\n"); + return 0; + } +} + +/* static utility functions for output_iris */ + +static void lumrow(unsigned char *rgbptr, unsigned char *lumptr, int n) +/* unsigned char *rgbptr, *lumptr; */ +/* int n; */ +{ + lumptr += CHANOFFSET(0); + while(n--) { + *lumptr = ILUM(rgbptr[OFFSET_R],rgbptr[OFFSET_G],rgbptr[OFFSET_B]); + lumptr += 4; + rgbptr += 4; + } +} + +static int compressrow(unsigned char *lbuf, unsigned char *rlebuf, int z, int cnt) +/* unsigned char *lbuf, *rlebuf; */ +/* int z, cnt; */ +{ + unsigned char *iptr, *ibufend, *sptr, *optr; + short todo, cc; + int count; + + lbuf += z; + iptr = lbuf; + ibufend = iptr+cnt*4; + optr = rlebuf; + + while(iptr<ibufend) { + sptr = iptr; + iptr += 8; + while((iptr<ibufend)&& ((iptr[-8]!=iptr[-4])||(iptr[-4]!=iptr[0]))) + iptr+=4; + iptr -= 8; + count = (iptr-sptr)/4; + while(count) { + todo = count>126 ? 126:count; + count -= todo; + *optr++ = 0x80|todo; + while(todo>8) { + optr[0] = sptr[0*4]; + optr[1] = sptr[1*4]; + optr[2] = sptr[2*4]; + optr[3] = sptr[3*4]; + optr[4] = sptr[4*4]; + optr[5] = sptr[5*4]; + optr[6] = sptr[6*4]; + optr[7] = sptr[7*4]; + + optr += 8; + sptr += 8*4; + todo -= 8; + } + while(todo--) { + *optr++ = *sptr; + sptr += 4; + } + } + sptr = iptr; + cc = *iptr; + iptr += 4; + while( (iptr<ibufend) && (*iptr == cc) ) + iptr += 4; + count = (iptr-sptr)/4; + while(count) { + todo = count>126 ? 126:count; + count -= todo; + *optr++ = todo; + *optr++ = cc; + } + } + *optr++ = 0; + return optr - (unsigned char *)rlebuf; +} + +short imb_saveiris(struct ImBuf * ibuf, int file, int flags) +{ + short zsize; + int ret; + + zsize = (ibuf->depth + 7) >> 3; + if (flags & IB_zbuf && ibuf->zbuf != 0) zsize = 8; + + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + test_endian_zbuf(ibuf); + + ret = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, file, ibuf->zbuf); + + /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */ + IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + test_endian_zbuf(ibuf); + + return(ret); +} + diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c new file mode 100644 index 00000000000..8132997e5cd --- /dev/null +++ b/source/blender/imbuf/intern/jpeg.c @@ -0,0 +1,629 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * jpeg.c + * + * $Id$ + */ + + +/* This little block needed for linking to Blender... */ +#include <stdio.h> +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_jpeg.h" + +#include "jpeglib.h" + +/* the types are from the jpeg lib */ +static void jpeg_error (j_common_ptr cinfo); +static void init_source(j_decompress_ptr cinfo); +static boolean fill_input_buffer(j_decompress_ptr cinfo); +static void skip_input_data(j_decompress_ptr cinfo, long num_bytes); +static void term_source(j_decompress_ptr cinfo); +static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, int size); +static boolean handle_app1 (j_decompress_ptr cinfo); +static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags); + + +/* strncasecmp hack */ +#ifdef WIN32 +#define strncasecmp(a, b, n) strncmp(a, b, n) +#endif + +/* + * Er zijn in principe vier verschillende jpeg formaten. + * + * 1. jpeg - standaard drukwerk, u & v op kwart van resolutie + * 2. jvid - standaard video u & v halve resolutie, frame opengeklapt + +type 3 is unsupported as of jul 05 2000 Frank. + + * 3. jstr - als 2, maar dan met twee losse fields weggeschreven + * moet baseline zijn + * moet rgb zijn + * moet samplingfactors goed hebben + + + * 4. jmax - geen scaling in de componenten + */ + +static int jpeg_failed = FALSE; +static int jpeg_default_quality; +static int ibuf_ftype; + +static void jpeg_error (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + jpeg_destroy(cinfo); + + jpeg_failed = TRUE; +} + +//---------------------------------------------------------- +// INPUT HANDLER FROM MEMORY +//---------------------------------------------------------- + +typedef struct { + unsigned char *buffer; + int filled; +} buffer_struct; + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + unsigned char *buffer; + int size; + JOCTET terminal[2]; +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +static void init_source(j_decompress_ptr cinfo) +{ +} + + +static boolean fill_input_buffer(j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Since we have given all we have got already + * we simply fake an end of file + */ + + src->pub.next_input_byte = src->terminal; + src->pub.bytes_in_buffer = 2; + src->terminal[0] = (JOCTET) 0xFF; + src->terminal[1] = (JOCTET) JPEG_EOI; + + return TRUE; +} + + +static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + src->pub.next_input_byte = src->pub.next_input_byte + num_bytes; +} + + +static void term_source(j_decompress_ptr cinfo) +{ +} + +static void memory_source(j_decompress_ptr cinfo, unsigned char *buffer, int size) +{ + my_src_ptr src; + + if (cinfo->src == NULL) + { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; + src->pub.term_source = term_source; + + src->pub.bytes_in_buffer = size; + src->pub.next_input_byte = buffer; + + src->buffer = buffer; + src->size = size; +} + + +#define MAKESTMT(stuff) do { stuff } while (0) + +#define INPUT_VARS(cinfo) \ + struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + const JOCTET * next_input_byte = datasrc->next_input_byte; \ + size_t bytes_in_buffer = datasrc->bytes_in_buffer + +/* Unload the local copies --- do this only at a restart boundary */ +#define INPUT_SYNC(cinfo) \ + ( datasrc->next_input_byte = next_input_byte, \ + datasrc->bytes_in_buffer = bytes_in_buffer ) + +/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */ +#define INPUT_RELOAD(cinfo) \ + ( next_input_byte = datasrc->next_input_byte, \ + bytes_in_buffer = datasrc->bytes_in_buffer ) + +/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. + * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, + * but we must reload the local copies after a successful fill. + */ +#define MAKE_BYTE_AVAIL(cinfo,action) \ + if (bytes_in_buffer == 0) { \ + if (! (*datasrc->fill_input_buffer) (cinfo)) \ + { action; } \ + INPUT_RELOAD(cinfo); \ + } \ + bytes_in_buffer-- + +/* Read a byte into variable V. + * If must suspend, take the specified action (typically "return FALSE"). + */ +#define INPUT_BYTE(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + V = GETJOCTET(*next_input_byte++); ) + +/* As above, but read two bytes interpreted as an unsigned 16-bit integer. + * V should be declared unsigned int or perhaps INT32. + */ +#define INPUT_2BYTES(cinfo,V,action) \ + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ + MAKE_BYTE_AVAIL(cinfo,action); \ + V += GETJOCTET(*next_input_byte++); ) + + +static boolean +handle_app1 (j_decompress_ptr cinfo) +{ + INT32 length, i; + char neogeo[128]; + + INPUT_VARS(cinfo); + + INPUT_2BYTES(cinfo, length, return FALSE); + length -= 2; + + if (length < 16) { + for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return FALSE); + length = 0; + if (strncmp(neogeo, "NeoGeo", 6) == 0) memcpy(&ibuf_ftype, neogeo + 6, 4); + ibuf_ftype = BIG_LONG(ibuf_ftype); + } + INPUT_SYNC(cinfo); /* do before skip_input_data */ + if (length > 0) (*cinfo->src->skip_input_data) (cinfo, length); + return TRUE; +} + + +static ImBuf * ibJpegImageFromCinfo(struct jpeg_decompress_struct * cinfo, int flags) +{ + JSAMPARRAY row_pointer; + JSAMPLE * buffer = 0; + int row_stride; + int x, y, depth, r, g, b, k; + struct ImBuf * ibuf = 0; + uchar * rect; + + /* eigen app1 handler installeren */ + ibuf_ftype = 0; + jpeg_set_marker_processor(cinfo, 0xe1, handle_app1); + cinfo->dct_method = JDCT_FLOAT; + + if (jpeg_read_header(cinfo, FALSE) == JPEG_HEADER_OK) { + x = cinfo->image_width; + y = cinfo->image_height; + depth = cinfo->num_components; + + if (cinfo->jpeg_color_space == JCS_YCCK) cinfo->out_color_space = JCS_CMYK; + + jpeg_start_decompress(cinfo); + + if (ibuf_ftype == 0) { + ibuf_ftype = JPG_STD; + if (cinfo->max_v_samp_factor == 1) { + if (cinfo->max_h_samp_factor == 1) ibuf_ftype = JPG_MAX; + else ibuf_ftype = JPG_VID; + } + } + + if (flags & IB_test) { + jpeg_abort_decompress(cinfo); + ibuf = IMB_allocImBuf(x, y, 8 * depth, 0, 0); + } else { + ibuf = IMB_allocImBuf(x, y, 8 * depth, IB_rect, 0); + + row_stride = cinfo->output_width * depth; + + row_pointer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, row_stride, 1); + + for (y = ibuf->y - 1; y >= 0; y--) { + jpeg_read_scanlines(cinfo, row_pointer, 1); + if (flags & IB_ttob) { + rect = (uchar *) (ibuf->rect + (ibuf->y - 1 - y) * ibuf->x); + } else { + rect = (uchar *) (ibuf->rect + y * ibuf->x); + } + buffer = row_pointer[0]; + + switch(depth) { + case 1: + for (x = ibuf->x; x > 0; x--) { + rect[3] = 255; + rect[0] = rect[1] = rect[2] = *buffer++; + rect += 4; + } + break; + case 3: + for (x = ibuf->x; x > 0; x--) { + rect[3] = 255; + rect[0] = *buffer++; + rect[1] = *buffer++; + rect[2] = *buffer++; + rect += 4; + } + break; + case 4: + for (x = ibuf->x; x > 0; x--) { + r = *buffer++; + g = *buffer++; + b = *buffer++; + k = *buffer++; + + k = 255 - k; + r -= k; + if (r & 0xffffff00) { + if (r < 0) r = 0; + else r = 255; + } + g -= k; + if (g & 0xffffff00) { + if (g < 0) g = 0; + else g = 255; + } + b -= k; + if (b & 0xffffff00) { + if (b < 0) b = 0; + else b = 255; + } + + rect[3] = 255 - k; + rect[2] = b; + rect[1] = g; + rect[0] = r; + rect += 4; + } + } + } + jpeg_finish_decompress(cinfo); + } + + jpeg_destroy((j_common_ptr) cinfo); + ibuf->ftype = ibuf_ftype; + } + + return(ibuf); +} + +ImBuf * imb_ibJpegImageFromFilename (char * filename, int flags) +{ + struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo; + struct jpeg_error_mgr jerr; + FILE * infile; + ImBuf * ibuf; + + if ((infile = fopen(filename, "rb")) == NULL) { + /*fprintf(stderr, "can't open %s\n", filename);*/ + return 0; + } + + cinfo->err = jpeg_std_error(&jerr); + jerr.error_exit = jpeg_error; + + jpeg_create_decompress(cinfo); + jpeg_stdio_src(cinfo, infile); + + ibuf = ibJpegImageFromCinfo(cinfo, flags); + + fclose(infile); + return(ibuf); +} + +ImBuf * imb_ibJpegImageFromMemory (unsigned char * buffer, int size, int flags) +{ + struct jpeg_decompress_struct _cinfo, *cinfo = &_cinfo; + struct jpeg_error_mgr jerr; + ImBuf * ibuf; + + cinfo->err = jpeg_std_error(&jerr); + jerr.error_exit = jpeg_error; + + jpeg_create_decompress(cinfo); + memory_source(cinfo, buffer, size); + + ibuf = ibJpegImageFromCinfo(cinfo, flags); + + return(ibuf); +} + + +static void write_jpeg(struct jpeg_compress_struct * cinfo, struct ImBuf * ibuf) +{ + JSAMPLE * buffer = 0; + JSAMPROW row_pointer[1]; + uchar * rect; + int x, y; + char neogeo[128]; + + + jpeg_start_compress(cinfo, TRUE); + + strcpy(neogeo, "NeoGeo"); + ibuf_ftype = BIG_LONG(ibuf->ftype); + + memcpy(neogeo + 6, &ibuf_ftype, 4); + jpeg_write_marker(cinfo, 0xe1, (JOCTET*) neogeo, 10); + + row_pointer[0] = + mallocstruct(JSAMPLE, + cinfo->input_components * + cinfo->image_width); + + for(y = ibuf->y - 1; y >= 0; y--){ + rect = (uchar *) (ibuf->rect + y * ibuf->x); + buffer = row_pointer[0]; + + switch(cinfo->in_color_space){ + case JCS_RGB: + for (x = 0; x < ibuf->x; x++) { + *buffer++ = rect[0]; + *buffer++ = rect[1]; + *buffer++ = rect[2]; + rect += 4; + } + break; + case JCS_GRAYSCALE: + for (x = 0; x < ibuf->x; x++) { + *buffer++ = rect[0]; + rect += 4; + } + break; + case JCS_UNKNOWN: + memcpy(buffer, rect, 4 * ibuf->x); + break; + /* default was missing... intentional ? */ + default: + ; /* do nothing */ + } + + jpeg_write_scanlines(cinfo, row_pointer, 1); + + if (jpeg_failed) break; + } + + if (jpeg_failed == FALSE) jpeg_finish_compress(cinfo); + free(row_pointer[0]); +} + + +static int init_jpeg(FILE * outfile, struct jpeg_compress_struct * cinfo, struct ImBuf *ibuf) +{ + int quality; + + quality = ibuf->ftype & 0xff; + if (quality <= 0) quality = jpeg_default_quality; + if (quality > 100) quality = 100; + + jpeg_create_compress(cinfo); + jpeg_stdio_dest(cinfo, outfile); + + cinfo->image_width = ibuf->x; + cinfo->image_height = ibuf->y; + + cinfo->in_color_space = JCS_RGB; + if (ibuf->depth == 8 && ibuf->cmap == 0) cinfo->in_color_space = JCS_GRAYSCALE; + if (ibuf->depth == 32) cinfo->in_color_space = JCS_UNKNOWN; + + switch(cinfo->in_color_space){ + case JCS_RGB: + cinfo->input_components = 3; + break; + case JCS_GRAYSCALE: + cinfo->input_components = 1; + break; + case JCS_UNKNOWN: + cinfo->input_components = 4; + break; + /* default was missing... intentional ? */ + default: + ; /* do nothing */ + } + jpeg_set_defaults(cinfo); + + /* eigen instellingen */ + + cinfo->dct_method = JDCT_FLOAT; + jpeg_set_quality(cinfo, quality, TRUE); + + return(0); +} + + +static int save_stdjpeg(char * name, struct ImBuf * ibuf) +{ + FILE * outfile; + struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; + struct jpeg_error_mgr jerr; + + if ((outfile = fopen(name, "wb")) == NULL) return(-1); + jpeg_default_quality = 75; + + cinfo->err = jpeg_std_error(&jerr); + jerr.error_exit = jpeg_error; + + init_jpeg(outfile, cinfo, ibuf); + + write_jpeg(cinfo, ibuf); + + fclose(outfile); + jpeg_destroy_compress(cinfo); + + if (jpeg_failed) remove(name); + return(jpeg_failed); +} + + +static int save_vidjpeg(char * name, struct ImBuf * ibuf) +{ + FILE * outfile; + struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; + struct jpeg_error_mgr jerr; + + if ((outfile = fopen(name, "wb")) == NULL) return(-1); + jpeg_default_quality = 90; + + cinfo->err = jpeg_std_error(&jerr); + jerr.error_exit = jpeg_error; + + init_jpeg(outfile, cinfo, ibuf); + + /* scalings factoren goedzetten */ + if (cinfo->in_color_space == JCS_RGB) { + cinfo->comp_info[0].h_samp_factor = 2; + cinfo->comp_info[0].v_samp_factor = 1; + } + + write_jpeg(cinfo, ibuf); + + fclose(outfile); + jpeg_destroy_compress(cinfo); + + if (jpeg_failed) remove(name); + return(jpeg_failed); +} + +static int save_jstjpeg(char * name, struct ImBuf * ibuf) +{ + char fieldname[1024]; + struct ImBuf * tbuf; + int oldy; +/* extern rectcpy(); */ + + tbuf = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 24, IB_rect, 0); + tbuf->ftype = ibuf->ftype; + tbuf->flags = ibuf->flags; + + oldy = ibuf->y; + ibuf->x *= 2; + ibuf->y /= 2; + + /* extra argument assumed to be 0 (nzc) */ +/* rectop(tbuf, ibuf, 0, 0, 0, 0, 32767, 32767, rectcpy); */ + IMB_rectop(tbuf, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + sprintf(fieldname, "%s.jf0", name); + + if (save_vidjpeg(fieldname, tbuf) == 0) { + /* extra argument assumed to be 0 (nzc) */ +/* rectop(tbuf, ibuf, 0, 0, tbuf->x, 0, 32767, 32767, rectcpy); */ + IMB_rectop(tbuf, ibuf, 0, 0, tbuf->x, 0, 32767, 32767, IMB_rectcpy, 0); + sprintf(fieldname, "%s.jf1", name); + save_vidjpeg(fieldname, tbuf); + } + + ibuf->y = oldy; + ibuf->x /= 2; + IMB_freeImBuf(tbuf); + + /* no return value was given, assuming 0 */ + return 0; +} + + +static int save_maxjpeg(char * name, struct ImBuf * ibuf) +{ + FILE * outfile; + struct jpeg_compress_struct _cinfo, *cinfo = &_cinfo; + struct jpeg_error_mgr jerr; + + if ((outfile = fopen(name, "wb")) == NULL) return(-1); + jpeg_default_quality = 100; + + cinfo->err = jpeg_std_error(&jerr); + jerr.error_exit = jpeg_error; + + init_jpeg(outfile, cinfo, ibuf); + + /* scalings factoren goedzetten */ + if (cinfo->in_color_space == JCS_RGB) { + cinfo->comp_info[0].h_samp_factor = 1; + cinfo->comp_info[0].v_samp_factor = 1; + } + + write_jpeg(cinfo, ibuf); + + fclose(outfile); + jpeg_destroy_compress(cinfo); + + if (jpeg_failed) remove(name); + return(jpeg_failed); +} + + +int imb_save_jpeg(char * name, struct ImBuf * ibuf, int flags) +{ + int ret; + + ibuf->flags = flags; + if (IS_stdjpg(ibuf)) ret = save_stdjpeg(name, ibuf); + else if (IS_jstjpg(ibuf)) ret = save_jstjpeg(name, ibuf); + else if (IS_maxjpg(ibuf)) ret = save_maxjpeg(name, ibuf); + else ret = save_vidjpeg(name, ibuf); + return(ret); +} + diff --git a/source/blender/imbuf/intern/matrix.h b/source/blender/imbuf/intern/matrix.h new file mode 100644 index 00000000000..62c1c3022d0 --- /dev/null +++ b/source/blender/imbuf/intern/matrix.h @@ -0,0 +1,86 @@ +/** + * matrix.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* rgbyuv is identiek aan rgbbeta */ + +float rgbyuv[4][4]={ /* afgeleid uit videoframer = Y Cr Cb in kopieen van Francois*/ + /* is identriek aan matrix van jpeg */ + .50000, .11400, -.08131, 0.0, /* b */ + -.33126, .58700, -.41869, 0.0, /* g */ + -.16874, .29900, .50000, 0.0, /* r */ + 128.0, 0.0, 128.0, 1.0}; + + /* b-y (u) y r-y (v) */ + + +float rgbbeta[4][4]={ /* afgeleid uit videoframer = Y Cr Cb in kopieen van Francois*/ + /* is identriek aan matrix van jpeg */ + .50000, .11400, -.08131, 0.0, /* b-y -> b */ + -.33126, .58700, -.41869, 0.0, /* y -> g */ + -.16874, .29900, .50000, 0.0, /* r-y -> r */ + 128.0, 0.0, 128.0, 1.0}; + + /* b-y y r-y */ + + + +float yuvrgb[4][4]={ + 1.77200, -0.34414, 0.0, 0.0, + 1.0, 1.0, 1.0, 0.0, + 0.0, -0.71414, 1.40200, 0.0, + -226.816, 135.460, -179.456, 1.0}; + +float rgb_to_bw[4][4]={ + .114, .114, .114, 0.0, + .587, .587, .587, 0.0, + .299, .299, .299, 0.0, + 0.5, 0.5, 0.5, 1.0}; + +float dyuvrgb_oud[4][4]={ + 1.0 , 1.0 , 1.0, 0.0, + 1.733, -0.337, 0.0, 0.0, + 0.0, -.698, 1.371, 0.0, + -221.8, 132.47, -175.5, 1.0}; + +float dyuvrgb[4][4]={ + 1.164 , 1.164 , 1.164, 0.0, + 2.018, -0.391, 0.0, 0.0, + 0.0, -0.813, 1.596, 0.0, + -276.7, 135.6, -222.7, 1.0}; + +float rgbdyuv[4][4]={ + 0.439, 0.098, -0.071, 0.0, + -0.291, 0.504, -0.368, 0.0, + -0.148, 0.257, 0.439, 0.0, + 128.0, 16.0, 128.0, 1.0}; diff --git a/source/blender/imbuf/intern/png_decode.c b/source/blender/imbuf/intern/png_decode.c new file mode 100644 index 00000000000..c4d795fa5af --- /dev/null +++ b/source/blender/imbuf/intern/png_decode.c @@ -0,0 +1,263 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * $Id$ + */ + +#include "png.h" + +#ifdef _WIN32 +#include "BLI_winstuff.h" +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_cmap.h" +#include "IMB_png.h" + + + +static int checkpng(unsigned char *mem) +{ + int ret_val = 0; + + if (mem) { + ret_val = !png_sig_cmp(mem, 0, 8); + } + + return(ret_val); +} + +int imb_is_a_png(void *buf) { + + return checkpng(buf); +} + +typedef struct PNGReadStruct { + unsigned char *data; + unsigned int size; + unsigned int seek; +}PNGReadStruct; + +static void +ReadData( + png_structp png_ptr, + png_bytep data, + png_size_t length); + +static void +ReadData( + png_structp png_ptr, + png_bytep data, + png_size_t length) +{ + PNGReadStruct *rs= (PNGReadStruct *) png_get_io_ptr(png_ptr); + + if (rs) { + if (length <= rs->size - rs->seek) { + memcpy(data, rs->data + rs->seek, length); + rs->seek += length; + return; + } + } + + printf("Reached EOF while decoding PNG\n"); + longjmp(png_jmpbuf(png_ptr), 1); +} + + +struct ImBuf *imb_png_decode(unsigned char *mem, int size, int flags) +{ + struct ImBuf *ibuf = 0; + png_structp png_ptr; + png_infop info_ptr; + unsigned char *pixels = 0; + png_bytepp row_pointers = 0; + png_uint_32 width, height; + int bit_depth, color_type; + PNGReadStruct ps; + + unsigned char *from, *to; + int i, bytesperpixel; + + if (checkpng(mem) == 0) return(0); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL); + if (png_ptr == NULL) { + printf("Cannot png_create_read_struct\n"); + return 0; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + printf("Cannot png_create_info_struct\n"); + return 0; + } + + ps.size = size; + ps.data = mem; + ps.seek = 0; + + png_set_read_fn(png_ptr, (void *) &ps, ReadData); + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + if (pixels) MEM_freeN(pixels); + if (row_pointers) MEM_freeN(row_pointers); + if (ibuf) IMB_freeImBuf(ibuf); + return 0; + } + + // png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); + + if (bit_depth == 16) { + png_set_strip_16(png_ptr); + bit_depth = 8; + } + + bytesperpixel = png_get_channels(png_ptr, info_ptr); + + switch(color_type) { + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + break; + case PNG_COLOR_TYPE_PALETTE: + png_set_palette_to_rgb(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + bytesperpixel = 4; + } else { + bytesperpixel = 3; + } + break; + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (bit_depth < 8) { + png_set_expand(png_ptr); + bit_depth = 8; + } + break; + default: + printf("PNG format not supported\n"); + longjmp(png_jmpbuf(png_ptr), 1); + } + + ibuf = IMB_allocImBuf(width, height, 8 * bytesperpixel, 0, 0); + + if (ibuf) { + ibuf->ftype = PNG; + } else { + printf("Couldn't allocate memory for PNG image\n"); + } + + if (ibuf && ((flags & IB_test) == 0)) { + imb_addrectImBuf(ibuf); + + pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "pixels"); + if (pixels == NULL) { + printf("Cannot allocate pixels array\n"); + longjmp(png_jmpbuf(png_ptr), 1); + } + + // allocate memory for an array of row-pointers + row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers"); + if (row_pointers == NULL) { + printf("Cannot allocate row-pointers array\n"); + longjmp(png_jmpbuf(png_ptr), 1); + } + + // set the individual row-pointers to point at the correct offsets + for (i = 0; i < ibuf->y; i++) { + row_pointers[ibuf->y-1-i] = (png_bytep) + ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char)); + } + + png_read_image(png_ptr, row_pointers); + + // copy image data + + to = (unsigned char *) ibuf->rect; + from = pixels; + + switch (bytesperpixel) { + case 4: + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to += 4; from += 4; + } + break; + case 3: + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = 0xff; + to += 4; from += 3; + } + break; + case 2: + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = to[1] = to[2] = from[0]; + to[3] = from[1]; + to += 4; from += 2; + } + break; + case 1: + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = to[1] = to[2] = from[0]; + to[3] = 0xff; + to += 4; from++; + } + break; + } + + png_read_end(png_ptr, info_ptr); + } + + // clean up + MEM_freeN(pixels); + MEM_freeN(row_pointers); + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + + return(ibuf); +} + diff --git a/source/blender/imbuf/intern/png_encode.c b/source/blender/imbuf/intern/png_encode.c new file mode 100644 index 00000000000..a4423f57830 --- /dev/null +++ b/source/blender/imbuf/intern/png_encode.c @@ -0,0 +1,236 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * $Id$ + */ + + +#include "png.h" + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_cmap.h" + +static void +WriteData( + png_structp png_ptr, + png_bytep data, + png_size_t length); + +static void +Flush( + png_structp png_ptr); + +static void +WriteData( + png_structp png_ptr, + png_bytep data, + png_size_t length) +{ + ImBuf *ibuf = (ImBuf *) png_get_io_ptr(png_ptr); + + // if buffer is to small increase it. + while (ibuf->encodedsize + length > ibuf->encodedbuffersize) { + imb_enlargeencodedbufferImBuf(ibuf); + } + + memcpy(ibuf->encodedbuffer + ibuf->encodedsize, data, length); + ibuf->encodedsize += length; +} + +static void +Flush( + png_structp png_ptr) +{ +} + +short IMB_png_encode(struct ImBuf *ibuf, int file, int flags) +{ + png_structp png_ptr; + png_infop info_ptr; + unsigned char *pixels = 0; + unsigned char *from, *to; + png_bytepp row_pointers = 0; + int i, bytesperpixel, color_type; + FILE *fp = 0; + + bytesperpixel = (ibuf->depth + 7) >> 3; + if ((bytesperpixel > 4) || (bytesperpixel == 2)) { + printf("imb_png_encode: unsupported bytes per pixel: %d\n", bytesperpixel); + return (0); + } + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL); + if (png_ptr == NULL) { + printf("Cannot png_create_write_struct\n"); + return 0; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + printf("Cannot png_create_info_struct\n"); + return 0; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_write_struct(&png_ptr, &info_ptr); + if (pixels) MEM_freeN(pixels); + if (row_pointers) MEM_freeN(row_pointers); + // printf("Aborting\n"); + if (fp) { + fflush(fp); + fclose(fp); + } + return 0; + } + + // copy image data + + pixels = MEM_mallocN(ibuf->x * ibuf->y * bytesperpixel * sizeof(unsigned char), "pixels"); + if (pixels == NULL) { + printf("Cannot allocate pixels array\n"); + return 0; + } + + from = (unsigned char *) ibuf->rect; + to = pixels; + + switch (bytesperpixel) { + case 4: + color_type = PNG_COLOR_TYPE_RGBA; + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to += 4; from += 4; + } + break; + case 3: + color_type = PNG_COLOR_TYPE_RGB; + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to += 3; from += 4; + } + break; + case 1: + color_type = PNG_COLOR_TYPE_GRAY; + for (i = ibuf->x * ibuf->y; i > 0; i--) { + to[0] = from[0]; + to++; from += 4; + } + break; + } + + if (flags & IB_mem) { + // create image in memory + imb_addencodedbufferImBuf(ibuf); + ibuf->encodedsize = 0; + + png_set_write_fn(png_ptr, + (png_voidp) ibuf, + WriteData, + Flush); + } else { + fp = fdopen(file, "wb"); + png_init_io(png_ptr, fp); + } + + /* + png_set_filter(png_ptr, 0, + PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | + PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | + PNG_FILTER_UP | PNG_FILTER_VALUE_UP | + PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | + PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| + PNG_ALL_FILTERS); + + png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); + */ + + // png image settings + png_set_IHDR(png_ptr, + info_ptr, + ibuf->x, + ibuf->y, + 8, + color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + // write the file header information + png_write_info(png_ptr, info_ptr); + + // allocate memory for an array of row-pointers + row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers"); + if (row_pointers == NULL) { + printf("Cannot allocate row-pointers array\n"); + return 0; + } + + // set the individual row-pointers to point at the correct offsets + for (i = 0; i < ibuf->y; i++) { + row_pointers[ibuf->y-1-i] = (png_bytep) + ((unsigned char *)pixels + (i * ibuf->x) * bytesperpixel * sizeof(unsigned char)); + } + + // write out the entire image data in one call + png_write_image(png_ptr, row_pointers); + + // write the additional chunks to the PNG file (not really needed) + png_write_end(png_ptr, info_ptr); + + // clean up + MEM_freeN(pixels); + MEM_freeN(row_pointers); + png_destroy_write_struct(&png_ptr, &info_ptr); + + if (fp) { + fflush(fp); + fclose(fp); + } + + return(1); +} + diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c new file mode 100644 index 00000000000..ef9c7271d7b --- /dev/null +++ b/source/blender/imbuf/intern/readimage.c @@ -0,0 +1,256 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * allocimbuf.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_amiga.h" +#include "IMB_iris.h" +#include "IMB_targa.h" +#include "IMB_png.h" +#include "IMB_hamx.h" +#include "IMB_jpeg.h" +#include "IMB_bmp.h" + +/* actually hard coded endianness */ +#define GET_BIG_LONG(x) (((uchar *) (x))[0] << 24 | ((uchar *) (x))[1] << 16 | ((uchar *) (x))[2] << 8 | ((uchar *) (x))[3]) +#define GET_LITTLE_LONG(x) (((uchar *) (x))[3] << 24 | ((uchar *) (x))[2] << 16 | ((uchar *) (x))[1] << 8 | ((uchar *) (x))[0]) +#define SWAP_L(x) (((x << 24) & 0xff000000) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff)) +#define SWAP_S(x) (((x << 8) & 0xff00) | ((x >> 8) & 0xff)) + +/* more endianness... should move to a separate file... */ +#if defined(__sgi) || defined (__sparc) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) +#define GET_ID GET_BIG_LONG +#define LITTLE_LONG SWAP_LONG +#else +#define GET_ID GET_LITTLE_LONG +#define LITTLE_LONG ENDIAN_NOP +#endif + +/* from misc_util: flip the bytes from x */ +#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) + +/* this one is only def-ed once, strangely... */ +#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) + +int IB_verbose = TRUE; + +ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) { + int len; + struct ImBuf *ibuf; + + if (mem == NULL) { + printf("Error in ibImageFromMemory: NULL pointer\n"); + } else { + if ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC)){ + return (imb_loadiris((uchar *) mem, flags)); + } else if ((BIG_LONG(mem[0]) & 0xfffffff0) == 0xffd8ffe0) { + return (imb_ibJpegImageFromMemory((uchar *)mem, size, flags)); + } + + if (GET_ID(mem) == CAT){ + mem += 3; + size -= 4; + while (size > 0){ + if (GET_ID(mem) == FORM){ + len = ((GET_BIG_LONG(mem+1) + 1) & ~1) + 8; + if ((GET_ID(mem+2) == ILBM) || (GET_ID(mem+2) == ANIM)) break; + mem = (int *)((uchar *)mem +len); + size -= len; + } else return(0); + } + } + + if (size > 0){ + if (GET_ID(mem) == FORM){ + if (GET_ID(mem+2) == ILBM){ + return (imb_loadamiga(mem, flags)); + } else if (GET_ID(mem+5) == ILBM){ /* animaties */ + return (imb_loadamiga(mem+3, flags)); + } else if (GET_ID(mem+2) == ANIM){ + return (imb_loadanim(mem, flags)); + } + } + } + + ibuf = imb_png_decode((uchar *)mem, size, flags); + if (ibuf) return(ibuf); + + ibuf = imb_bmp_decode((uchar *)mem, size, flags); + if (ibuf) return(ibuf); + + ibuf = imb_loadtarga((uchar *)mem, flags); + if (ibuf) return(ibuf); + + if (IB_verbose) fprintf(stderr, "Unknown fileformat\n"); + } + + return (0); +} + + +struct ImBuf *IMB_loadiffmem(int *mem, int flags) { + int len,maxlen; + struct ImBuf *ibuf; + + // IMB_loadiffmem shouldn't be used anymore in new development + // it's still here to be backwards compatible... + + maxlen= (GET_BIG_LONG(mem+1) + 1) & ~1; + + if (GET_ID(mem) == CAT){ + mem += 3; + maxlen -= 4; + while(maxlen > 0){ + if (GET_ID(mem) == FORM){ + len = ((GET_BIG_LONG(mem+1) + 1) & ~1) + 8; + if ((GET_ID(mem+2) == ILBM) || (GET_ID(mem+2) == ANIM)) break; + mem = (int *)((uchar *)mem +len); + maxlen -= len; + } else return(0); + } + } + + if (maxlen > 0){ + if (GET_ID(mem) == FORM){ + if (GET_ID(mem+2) == ILBM){ + return (imb_loadamiga(mem, flags)); + } else if (GET_ID(mem+5) == ILBM){ /* animaties */ + return (imb_loadamiga(mem+3, flags)); + } else if (GET_ID(mem+2) == ANIM){ + return (imb_loadanim(mem, flags)); + } + } else if ((GS(mem) == IMAGIC) || (GSS(mem) == IMAGIC)){ + return (imb_loadiris((uchar *) mem,flags)); + } else if ((BIG_LONG(mem[0]) & 0xfffffff0) == 0xffd8ffe0) { + return (0); + } + } + + ibuf = imb_loadtarga((uchar *) mem,flags); + if (ibuf) return(ibuf); + + if (IB_verbose) fprintf(stderr,"Unknown fileformat\n"); + return (0); +} + +struct ImBuf *IMB_loadifffile(int file, int flags) { + struct ImBuf *ibuf; + int size, *mem; + + if (file == -1) return (0); + + size = BLI_filesize(file); + +#if defined(AMIGA) || defined(__BeOS) || defined(WIN32) + mem= (int *)malloc(size); + if (mem==0) { + printf("Out of mem\n"); + return (0); + } + + if (read(file, mem, size)!=size){ + printf("Read Error\n"); + free(mem); + return (0); + } + + ibuf = IMB_ibImageFromMemory(mem, size, flags); + free(mem); + + /* for jpeg read */ + lseek(file, 0L, SEEK_SET); + +#else + mem= (int *)mmap(0,size,PROT_READ,MAP_SHARED,file,0); + if (mem==(int *)-1){ + printf("Couldn't get mapping\n"); + return (0); + } + + ibuf = IMB_ibImageFromMemory(mem, size, flags); + + if (munmap( (void *) mem, size)){ + printf("Couldn't unmap file.\n"); + } +#endif + return(ibuf); +} + + +struct ImBuf *IMB_loadiffname(char *naam, int flags) { + int file; + struct ImBuf *ibuf; + int buf[1]; + + file = open(naam, O_BINARY|O_RDONLY); + + if (file == -1) return (0); + + ibuf= IMB_loadifffile(file, flags); + + if (ibuf == 0) { + if (read(file, buf, 4) != 4) buf[0] = 0; + if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0) + ibuf = imb_ibJpegImageFromFilename(naam, flags); + } + + if (ibuf) { + strncpy(ibuf->name, naam, sizeof(ibuf->name)); + if (flags & IB_fields) IMB_de_interlace(ibuf); + } + close(file); + return(ibuf); +} + +struct ImBuf *IMB_testiffname(char *naam,int flags) { + int file; + struct ImBuf *ibuf; + + flags |= IB_test; + file = open(naam,O_BINARY|O_RDONLY); + + if (file<=0) return (0); + + ibuf=IMB_loadifffile(file,flags); + if (ibuf) { + strncpy(ibuf->name, naam, sizeof(ibuf->name)); + } + close(file); + return(ibuf); +} diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c new file mode 100644 index 00000000000..32f01eea6c8 --- /dev/null +++ b/source/blender/imbuf/intern/rectop.c @@ -0,0 +1,135 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * allocimbuf.c + * + * $Id$ + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" + +void IMB_rectcpy(unsigned int *drect, unsigned int *srect, int x, int dummy) +{ + memcpy(drect,srect, x * sizeof(int)); +} + + +void IMB_rectfill(unsigned int *drect, unsigned int *srect, int x, int value) +{ + for (;x > 0; x--) *drect++ = value; +} + +void IMB_rectop(struct ImBuf *dbuf, + struct ImBuf *sbuf, + int destx, + int desty, + int srcx, + int srcy, + int width, + int height, + void (*operation)(unsigned int *, unsigned int*, int, int), + int value) +{ + unsigned int *drect,*srect; + + if (dbuf == 0) return; + if (operation == 0) return; + + if (destx < 0){ + srcx -= destx ; + width += destx ; + destx = 0; + } + if (srcx < 0){ + destx -= srcx ; + width += destx ; + srcx = 0; + } + if (desty < 0){ + srcy -= desty ; + height += desty ; + desty = 0; + } + if (srcy < 0){ + desty -= srcy ; + height += desty ; + srcy = 0; + } + + if (width > dbuf->x - destx) width = dbuf->x - destx; + if (height > dbuf->y - desty) height = dbuf->y - desty; + if (sbuf){ + if (width > sbuf->x - srcx) width = sbuf->x - srcx; + if (height > sbuf->y - srcy) height = sbuf->y - srcy; + } + + if (width <= 0) return; + if (height <= 0) return; + + drect = dbuf->rect; + if (sbuf) srect = sbuf->rect; + + drect += desty * dbuf->x; + drect += destx; + destx = dbuf->x; + + if (sbuf) { + srect += srcy * sbuf->x; + srect += srcx; + srcx = sbuf->x; + } else{ + srect = drect; + srcx = destx; + } + + for (;height > 0; height--){ + operation(drect,srect,width, value); + drect += destx; + srect += srcx; + } +} + + +void IMB_rectoptot(struct ImBuf *dbuf, + struct ImBuf *sbuf, + void (*operation)(unsigned int *, unsigned int*, int, int), + int value) +{ + IMB_rectop(dbuf,sbuf,0,0,0,0,32767,32767,operation, value); +} diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c new file mode 100644 index 00000000000..edd82347a8c --- /dev/null +++ b/source/blender/imbuf/intern/rotate.c @@ -0,0 +1,71 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * rotate.c + * + * $Id$ + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" + +void IMB_flipy(struct ImBuf * ibuf) +{ + short x,y,backx; + unsigned int *top,*bottom,temp; + + if (ibuf == 0) return; + if (ibuf->rect == 0) return; + + x = ibuf->x; + y = ibuf->y; + backx = x<<1; + + top = ibuf->rect; + bottom = top + ((y-1) * x); + y >>= 1; + + for(;y>0;y--){ + for(x = ibuf->x; x > 0; x--){ + temp = *top; + *(top++) = *bottom; + *(bottom++) = temp; + } + bottom -= backx; + } +} diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c new file mode 100644 index 00000000000..eb397f6bced --- /dev/null +++ b/source/blender/imbuf/intern/scaling.c @@ -0,0 +1,699 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * allocimbuf.c + * + * $Id$ + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_filter.h" + +/************************************************************************/ +/* SCALING */ +/************************************************************************/ + + +struct ImBuf *IMB_half_x(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + uchar *p1,*_p1,*dest; + short a,r,g,b,x,y; + + if (ibuf1==0) return (0); + if (ibuf1->rect == 0) return (0); + + if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1)); + + ibuf2 = IMB_allocImBuf((ibuf1->x)/2 , ibuf1->y , ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + _p1 = (uchar *) ibuf1->rect; + dest=(uchar *) ibuf2->rect; + + for(y=ibuf2->y;y>0;y--){ + p1 = _p1; + for(x = ibuf2->x ; x>0 ; x--){ + a = *(p1++) ; + b = *(p1++) ; + g = *(p1++) ; + r = *(p1++); + a += *(p1++) ; + b += *(p1++) ; + g += *(p1++) ; + r += *(p1++); + *(dest++) = a >> 1; + *(dest++) = b >> 1; + *(dest++) = g >> 1; + *(dest++) = r >> 1; + } + _p1 += (ibuf1->x << 2); + } + return (ibuf2); +} + + +struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + int *p1,*dest, i, col; + + if (ibuf1==0) return (0); + if (ibuf1->rect == 0) return (0); + + ibuf2 = IMB_allocImBuf(2 * ibuf1->x , ibuf1->y , ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + p1 = (int *) ibuf1->rect; + dest=(int *) ibuf2->rect; + + for(i = ibuf1->y * ibuf1->x ; i>0 ; i--) { + col = *p1++; + *dest++ = col; + *dest++ = col; + } + + return (ibuf2); +} + +struct ImBuf *IMB_double_x(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + + if (ibuf1==0) return (0); + if (ibuf1->rect == 0) return (0); + + ibuf2 = IMB_double_fast_x(ibuf1); + + imb_filterx(ibuf2); + return (ibuf2); +} + + +struct ImBuf *IMB_half_y(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + uchar *p1,*p2,*_p1,*dest; + short a,r,g,b,x,y; + + if (ibuf1==0) return (0); + if (ibuf1->rect == 0) return (0); + if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1)); + + ibuf2 = IMB_allocImBuf(ibuf1->x , (ibuf1->y) / 2 , ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + _p1 = (uchar *) ibuf1->rect; + dest=(uchar *) ibuf2->rect; + + for(y=ibuf2->y ; y>0 ; y--){ + p1 = _p1; + p2 = _p1 + (ibuf1->x << 2); + for(x = ibuf2->x ; x>0 ; x--){ + a = *(p1++) ; + b = *(p1++) ; + g = *(p1++) ; + r = *(p1++); + a += *(p2++) ; + b += *(p2++) ; + g += *(p2++) ; + r += *(p2++); + *(dest++) = a >> 1; + *(dest++) = b >> 1; + *(dest++) = g >> 1; + *(dest++) = r >> 1; + } + _p1 += (ibuf1->x << 3); + } + return (ibuf2); +} + + +struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + int *p1, *dest1, *dest2; + short x,y; + + if (ibuf1==0) return (0); + if (ibuf1->rect == 0) return (0); + + ibuf2 = IMB_allocImBuf(ibuf1->x , 2 * ibuf1->y , ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + p1 = (int *) ibuf1->rect; + dest1=(int *) ibuf2->rect; + + for(y = ibuf1->y ; y>0 ; y--){ + dest2 = dest1 + ibuf2->x; + for(x = ibuf2->x ; x>0 ; x--) *dest1++ = *dest2++ = *p1++; + dest1 = dest2; + } + + return (ibuf2); +} + +struct ImBuf *IMB_double_y(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + + if (ibuf1==0) return (0); + if (ibuf1->rect == 0) return (0); + + ibuf2 = IMB_double_fast_y(ibuf1); + + IMB_filtery(ibuf2); + return (ibuf2); +} + + +struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + uchar *p1,*p2,*dest; + int x,y; + + if (ibuf1 == 0) return (0); + if (ibuf1->rect == 0) return (0); + + if (ibuf1->x <= 1) return(IMB_half_y(ibuf1)); + if (ibuf1->y <= 1) return(IMB_half_x(ibuf1)); + + ibuf2=IMB_allocImBuf((ibuf1->x)/2,(ibuf1->y)/2,ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + p1 = (uchar *) ibuf1->rect; + dest=(uchar *) ibuf2->rect; + + for(y=ibuf2->y;y>0;y--){ + p2 = p1 + (ibuf1->x << 2); + for(x=ibuf2->x;x>0;x--){ + dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2; + dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2; + dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2; + dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2; + p1 += 8; + p2 += 8; + dest += 4; + } + p1=p2; + if(ibuf1->x & 1) { + p1+=4; + } + } + return (ibuf2); +} + + + +struct ImBuf *IMB_onethird(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + uchar *p1,*p2,*p3,*dest; + short a,r,g,b,x,y,i; + + if (ibuf1 == 0) return (0); + if (ibuf1->rect == 0) return (0); + + ibuf2=IMB_allocImBuf((ibuf1->x)/3,(ibuf1->y)/3,ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + p1 = (uchar *) ibuf1->rect; + dest=(uchar *) ibuf2->rect; + + for(y=ibuf2->y;y>0;y--){ + p2 = p1 + (ibuf1->x << 2); + p3 = p2 + (ibuf1->x << 2); + for(x=ibuf2->x;x>0;x--){ + a=r=g=b=0; + for (i=3;i>0;i--){ + a += *(p1++) + *(p2++) + *(p3++); + b += *(p1++) + *(p2++) + *(p3++); + g += *(p1++) + *(p2++) + *(p3++); + r += *(p1++) + *(p2++) + *(p3++); + } + *(dest++) = a/9; + *(dest++) = b/9; + *(dest++) = g/9; + *(dest++) = r/9; + } + p1=p3; + } + return (ibuf2); +} + + +struct ImBuf *IMB_halflace(struct ImBuf *ibuf1) +{ + struct ImBuf *ibuf2; + uchar *p1,*p2,*dest; + short a,r,g,b,x,y,i; + + if (ibuf1 == 0) return (0); + if (ibuf1->rect == 0) return (0); + + ibuf2=IMB_allocImBuf((ibuf1->x)/4,(ibuf1->y)/2,ibuf1->depth,1,0); + if (ibuf2==0) return (0); + + p1 = (uchar *) ibuf1->rect; + dest=(uchar *) ibuf2->rect; + + for(y= ibuf2->y / 2 ; y>0;y--){ + p2 = p1 + (ibuf1->x << 3); + for(x = 2 * ibuf2->x;x>0;x--){ + a=r=g=b=0; + for (i=4;i>0;i--){ + a += *(p1++) + *(p2++); + b += *(p1++) + *(p2++); + g += *(p1++) + *(p2++); + r += *(p1++) + *(p2++); + } + *(dest++) = a >> 3; + *(dest++) = b >> 3; + *(dest++) = g >> 3; + *(dest++) = r >> 3; + } + p1 = p2; + } + return (ibuf2); +} + + +static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx) +{ + uchar *rect,*_newrect,*newrect; + float sample, add, val, nval; + int x, y, i; + + if (ibuf == 0) return(0); + if (ibuf->rect == 0) return(ibuf); + + _newrect = (uchar *) malloc(newx * ibuf->y * sizeof(int)); + if (_newrect == 0) return(ibuf); + + add = (ibuf->x - 0.001) / newx; + + /* all four components, rgba/abgr */ + for(i=3 ; i >= 0 ; i--){ + rect = (uchar *) ibuf->rect; + rect += i; + newrect = _newrect + i; + + for (y = ibuf->y; y>0 ; y--){ + val = sample = 0.0; + + for (x = newx ; x>0 ; x--){ + nval = - val * sample; + sample += add; + + while (sample >= 1.0){ + sample -= 1.0; + nval += *rect; + rect += 4; + } + val = *rect; + rect += 4; + nval += sample * val; + sample -= 1.0; + *newrect = (nval/add) + 0.5; + newrect += 4; + } + } + } + + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + ibuf->x = newx; + return(ibuf); +} + + +static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy) +{ + uchar *rect,*_newrect,*newrect; + float sample,add,val,nval; + int x,y,i,skipx; + + if (ibuf == 0) return(0); + if (ibuf->rect == 0) return(ibuf); + + _newrect = (uchar *) malloc(newy * ibuf->x * sizeof(int)); + if (_newrect == 0) return(ibuf); + + add = (ibuf->y - 0.001) / newy; + skipx = 4 * ibuf->x; + + /* all four components, rgba/abgr */ + for(i=3 ; i>=0 ; i--){ + for (x = skipx - 4; x>=0 ; x-= 4){ + rect = ((uchar *) ibuf->rect) + i + x; + newrect = _newrect + i + x; + val = sample = 0.0; + + for (y = newy ; y>0 ; y--){ + nval = - val * sample; + sample += add; + + while (sample >= 1.0){ + sample -= 1.0; + nval += *rect; + rect += skipx; + } + val = *rect; + rect += skipx; + nval += sample * val; + sample -= 1.0; + *newrect = (nval/add) + 0.5; + newrect += skipx; + } + } + } + + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + ibuf->y = newy; + return(ibuf); +} + + +static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) +{ + uchar *rect,*_newrect,*newrect; + float sample,add; + float val_a,nval_a,diff_a; + float val_b,nval_b,diff_b; + float val_g,nval_g,diff_g; + float val_r,nval_r,diff_r; + int x,y; + + if (ibuf == 0) return(0); + if (ibuf->rect == 0) return(ibuf); + + _newrect = (uchar *) malloc(newx * ibuf->y * sizeof(int)); + if (_newrect == 0) return(ibuf); + + add = (ibuf->x - 1.001) / (newx - 1.0); + + rect = (uchar *) ibuf->rect; + newrect = _newrect; + + for (y = ibuf->y; y>0 ; y--){ + + sample = 0; + val_a = rect[0] ; + nval_a = rect[4]; + diff_a = nval_a - val_a ; + val_a += 0.5; + + val_b = rect[1] ; + nval_b = rect[5]; + diff_b = nval_b - val_b ; + val_b += 0.5; + + val_g = rect[2] ; + nval_g = rect[6]; + diff_g = nval_g - val_g ; + val_g += 0.5; + + val_r = rect[3] ; + nval_r = rect[7]; + diff_r = nval_r - val_r ; + val_r += 0.5; + + rect += 8; + for (x = newx ; x>0 ; x--){ + if (sample >= 1.0){ + sample -= 1.0; + val_a = nval_a ; + nval_a = rect[0] ; + diff_a = nval_a - val_a ; + val_a += 0.5; + + val_b = nval_b ; + nval_b = rect[1] ; + diff_b = nval_b - val_b ; + val_b += 0.5; + + val_g = nval_g ; + nval_g = rect[2] ; + diff_g = nval_g - val_g ; + val_g += 0.5; + + val_r = nval_r ; + nval_r = rect[3] ; + diff_r = nval_r - val_r ; + val_r += 0.5; + rect += 4; + } + newrect[0] = val_a + sample * diff_a; + newrect[1] = val_b + sample * diff_b; + newrect[2] = val_g + sample * diff_g; + newrect[3] = val_r + sample * diff_r; + newrect += 4; + sample += add; + } + } + + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + ibuf->x = newx; + return(ibuf); +} + + +static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy) +{ + uchar *rect,*_newrect,*newrect; + float sample,add,val,nval,diff; + int x,y,i,skipx; + + if (ibuf == 0) return(0); + if (ibuf->rect == 0) return(ibuf); + + _newrect = (uchar *)malloc(newy * ibuf->x * sizeof(int)); + if (_newrect == 0) return(ibuf); + + add = (ibuf->y - 1.001) / (newy - 1.0); + skipx = 4 * ibuf->x; + + /* all four components, rgba/abgr */ + for(i=3 ; i>=0 ; i--){ + for (x = skipx - 4; x >= 0 ; x -= 4){ + rect = (uchar *) ibuf->rect; + rect += i + x; + newrect = _newrect + i + x; + + sample = 0; + val = *rect ; + rect += skipx; + nval = *rect; + rect += skipx; + diff = nval - val; + val += 0.5; + + for (y = newy ; y>0 ; y--){ + if (sample >= 1.0){ + sample -= 1.0; + val = nval; + nval = *rect; + rect += skipx; + diff = nval - val; + val += 0.5; + } + *newrect = val + sample * diff; + newrect += skipx; + sample += add; + } + } + } + + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + ibuf->y = newy; + return(ibuf); +} + +static void scalefast_Z_ImBuf(ImBuf *ibuf, short newx, short newy) +{ + unsigned int *rect,*_newrect,*newrect; + int x,y; + int ofsx,ofsy,stepx,stepy; + + if (ibuf->zbuf) { + _newrect = malloc(newx * newy * sizeof(int)); + if (_newrect == 0) return; + + stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5; + stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5; + ofsy = 32768; + + newrect = _newrect; + + for (y = newy; y > 0 ; y--){ + rect = (unsigned int*) ibuf->zbuf; + rect += (ofsy >> 16) * ibuf->x; + ofsy += stepy; + ofsx = 32768; + for (x = newx ; x > 0 ; x--){ + *newrect++ = rect[ofsx >> 16]; + ofsx += stepx; + } + } + + IMB_freezbufImBuf(ibuf); + ibuf->mall |= IB_zbuf; + ibuf->zbuf = (int*) _newrect; + } +} + +struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) +{ + if (ibuf == 0) return (0); + if (ibuf->rect == 0) return (ibuf); + + // scaleup / scaledown functions below change ibuf->x and ibuf->y + // so we first scale the Z-buffer (if any) + scalefast_Z_ImBuf(ibuf, newx, newy); + + if (newx < ibuf->x) if (newx) scaledownx(ibuf,newx); + if (newy < ibuf->y) if (newy) scaledowny(ibuf,newy); + if (newx > ibuf->x) if (newx) scaleupx(ibuf,newx); + if (newy > ibuf->y) if (newy) scaleupy(ibuf,newy); + + return(ibuf); +} + + +struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, short newx, short newy) +{ + unsigned int *rect,*_newrect,*newrect; + int x,y; + int ofsx,ofsy,stepx,stepy; + + if (ibuf == 0) return(0); + if (ibuf->rect == 0) return(ibuf); + + if (newx == ibuf->x && newy == ibuf->y) return(ibuf); + + _newrect = malloc(newx * newy * sizeof(int)); + if (_newrect == 0) return(ibuf); + + newrect = _newrect; + stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5; + stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5; + ofsy = 32768; + + for (y = newy; y > 0 ; y--){ + rect = ibuf->rect; + rect += (ofsy >> 16) * ibuf->x; + ofsy += stepy; + ofsx = 32768; + for (x = newx ; x>0 ; x--){ + *newrect++ = rect[ofsx >> 16]; + ofsx += stepx; + } + } + + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = _newrect; + + scalefast_Z_ImBuf(ibuf, newx, newy); + + ibuf->x = newx; + ibuf->y = newy; + return(ibuf); +} + + +static struct ImBuf *generic_fieldscale(struct ImBuf *ibuf, short newx, short newy, struct ImBuf *(*scalefunc)(ImBuf *, short, short) ) +{ + struct ImBuf *sbuf1, *sbuf2; +/* extern void rectcpy(); */ + + sbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, IB_rect, 0); + sbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, IB_rect, 0); + + ibuf->x *= 2; + /* more args needed, 0 assumed... (nzc) */ +/* rectop(sbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, rectcpy); */ +/* rectop(sbuf2, ibuf, 0, 0, sbuf2->x, 0, 32767, 32767, rectcpy); */ + IMB_rectop(sbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectop(sbuf2, ibuf, 0, 0, sbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); + + imb_freerectImBuf(ibuf); + ibuf->x = newx; + ibuf->y = newy; + imb_addrectImBuf(ibuf); + + scalefunc(sbuf1, newx, newy / 2); + scalefunc(sbuf2, newx, newy / 2); + + ibuf->x *= 2; + + /* more args needed, 0 assumed... (nzc) */ +/* rectop(ibuf, sbuf1, 0, 0, 0, 0, 32767, 32767, rectcpy); */ +/* rectop(ibuf, sbuf2, sbuf2->x, 0, 0, 0, 32767, 32767, rectcpy); */ + IMB_rectop(ibuf, sbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectop(ibuf, sbuf2, sbuf2->x, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + + ibuf->x /= 2; + + IMB_freeImBuf(sbuf1); + IMB_freeImBuf(sbuf2); + + return(ibuf); +} + + +struct ImBuf *IMB_scalefastfieldImBuf(struct ImBuf *ibuf, + short newx, + short newy) +{ + return(generic_fieldscale(ibuf, newx, newy, IMB_scalefastImBuf)); +} + +struct ImBuf *IMB_scalefieldImBuf(struct ImBuf *ibuf, short newx, short newy) +{ + return(generic_fieldscale(ibuf, newx, newy, IMB_scaleImBuf)); +} diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c new file mode 100644 index 00000000000..dd1451a939a --- /dev/null +++ b/source/blender/imbuf/intern/targa.c @@ -0,0 +1,632 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * $Id$ + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#include <io.h> +#endif +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +#include "IMB_cmap.h" +#include "IMB_targa.h" + + +/* this one is only def-ed once, strangely... related to GS? */ +#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) + +/***/ + +typedef struct TARGA +{ + unsigned char numid; + unsigned char maptyp; + unsigned char imgtyp; + short maporig; + short mapsize; + unsigned char mapbits; + short xorig; + short yorig; + short xsize; + short ysize; + unsigned char pixsize; + unsigned char imgdes; +} TARGA; + +/***/ + +static int tga_out1(unsigned int data, FILE *file) +{ + uchar *p; + + p = (uchar *) & data; + if (putc(p[0],file) == EOF) return(EOF); + return (~EOF); +} + +static int tga_out2(unsigned int data, FILE * file) +{ + uchar *p; + + p = (uchar *) & data; + if (putc(p[0],file) == EOF) return(EOF); + if (putc(p[1],file) == EOF) return(EOF); + return (~EOF); +} + + +static int tga_out3(unsigned int data, FILE * file) +{ + uchar *p; + + p = (uchar *) & data; + if (putc(p[2],file) == EOF) return(EOF); + if (putc(p[1],file) == EOF) return(EOF); + if (putc(p[0],file) == EOF) return(EOF); + return (~EOF); +} + + +static int tga_out4(unsigned int data, FILE * file) +{ + uchar *p; + + p = (uchar *) & data; + /* volgorde = bgra */ + if (putc(p[2],file) == EOF) return(EOF); + if (putc(p[1],file) == EOF) return(EOF); + if (putc(p[0],file) == EOF) return(EOF); + if (putc(p[3],file) == EOF) return(EOF); + return (~EOF); +} + +static short makebody_tga(ImBuf * ibuf, FILE * file, int (*out)(unsigned int, FILE*)) +{ + register int last,this; + register int copy, bytes; + register unsigned int *rect, *rectstart, *temp; + int y; + + for (y = 0; y < ibuf->y; y++) { + bytes = ibuf->x - 1; + rectstart = rect = ibuf->rect + (y * ibuf->x); + last = *rect++; + this = *rect++; + copy = last^this; + while (bytes > 0){ + if (copy){ + do{ + last = this; + this = *rect++; + if (last == this){ + if (this == rect[-3]){ /* drie dezelfde? */ + bytes --; /* bytes goed zetten */ + break; + } + } + }while (--bytes != 0); + + copy = rect-rectstart; + copy --; + if (bytes) copy -= 2; + + temp = rect; + rect = rectstart; + + while (copy){ + last = copy; + if (copy>=128) last = 128; + copy -= last; + if (fputc(last-1,file) == EOF) return(0); + do{ + if (out(*rect++,file) == EOF) return(0); + }while(--last != 0); + } + rectstart = rect; + rect = temp; + last = this; + + copy = FALSE; + } else { + while (*rect++ == this){ /* zoek naar eerste afwijkende byte */ + if (--bytes == 0) break; /* of einde regel */ + } + rect --; + copy = rect-rectstart; + rectstart = rect; + bytes --; + this = *rect++; + + while (copy){ + if (copy>128){ + if (fputc(255,file) == EOF) return(0); + copy -= 128; + } else { + if (copy == 1){ + if (fputc(0,file) == EOF) return(0); + } else if (fputc(127 + copy,file) == EOF) return(0); + copy = 0; + } + if (out(last,file) == EOF) return(0); + } + copy=TRUE; + } + } + } + return (1); +} + +static int dumptarga(struct ImBuf * ibuf, FILE * file) +{ + int size; + uchar *rect; + + if (ibuf == 0) return (0); + if (ibuf->rect == 0) return (0); + + size = ibuf->x * ibuf->y; + rect = (uchar *) ibuf->rect; + + if (ibuf->depth <= 8) { + while(size > 0){ + if (putc(*rect, file) == EOF) return (0); + size--; + rect += 4; + } + } else if (ibuf->depth <= 16) { + while(size > 0){ + putc(rect[0], file); + if (putc(rect[1], file) == EOF) return (0); + size--; + rect += 4; + } + } else if (ibuf->depth <= 24) { + while(size > 0){ + putc(rect[2], file); + putc(rect[1], file); + if (putc(rect[0], file) == EOF) return (0); + size--; + rect += 4; + } + } else if (ibuf->depth <= 32) { + while(size > 0){ + putc(rect[2], file); + putc(rect[1], file); + putc(rect[0], file); + if (putc(rect[3], file) == EOF) return (0); + size--; + rect += 4; + } + } else return (0); + + return (1); +} + + +short imb_savetarga(struct ImBuf * ibuf, int file, int flags) +{ + char buf[20]; + FILE *fildes; + int i; + short ok; + + if (ibuf == 0) return (0); + if (ibuf->rect == 0) return (0); + + memset(buf,0,sizeof(buf)); + + /* buf[0] = 0; lengte string */ + + buf[16] = (ibuf->depth + 0x7 ) & ~0x7; + if (ibuf->cmap) { + buf[1] = 1; + buf[2] = 9; + buf[3] = ibuf->mincol & 0xff; + buf[4] = ibuf->mincol >> 8; + buf[5] = ibuf->maxcol & 0xff; + buf[6] = ibuf->maxcol >> 8; + buf[7] = 24; + if ((flags & IB_ttob) == 0) { + IMB_flipy(ibuf); + buf[17] = 0x20; + } + } else if (ibuf->depth > 8 ){ + buf[2] = 10; + } else{ + buf[2] = 11; + } + + if (ibuf->ftype == RAWTGA) buf[2] &= ~8; + + buf[8] = ibuf->xorig & 0xff; + buf[9] = ibuf->xorig >> 8; + buf[10] = ibuf->yorig & 0xff; + buf[11] = ibuf->yorig >> 8; + + buf[12] = ibuf->x & 0xff; + buf[13] = ibuf->x >> 8; + buf[14] = ibuf->y & 0xff; + buf[15] = ibuf->y >> 8; + + if (flags & IB_ttob) buf[17] ^= 0x20; + + if (write(file, buf, 18) != 18) return (0); + if (ibuf->cmap){ + for (i = 0 ; i<ibuf->maxcol ; i++){ + if (write(file,((uchar *)(ibuf->cmap + i)) + 1,3) != 3) return (0); + } + } + fildes = fdopen(file,"ab"); + + if (ibuf->cmap && (flags & IB_cmap) == 0) IMB_converttocmap(ibuf); + + if (ibuf->ftype == RAWTGA) { + ok = dumptarga(ibuf, fildes); + } else { + switch((ibuf->depth + 7) >> 3){ + case 1: + ok = makebody_tga(ibuf, fildes, tga_out1); + break; + case 2: + ok = makebody_tga(ibuf, fildes, tga_out2); + break; + case 3: + ok = makebody_tga(ibuf, fildes, tga_out3); + break; + case 4: + ok = makebody_tga(ibuf, fildes, tga_out4); + break; + } + } + + fclose(fildes); + return (ok); +} + + +static int checktarga(TARGA *tga, unsigned char *mem) +{ + tga->numid = mem[0]; + tga->maptyp = mem[1]; + tga->imgtyp = mem[2]; + + tga->maporig = GSS(mem+3); + tga->mapsize = GSS(mem+5); + tga->mapbits = mem[7]; + tga->xorig = GSS(mem+8); + tga->yorig = GSS(mem+10); + tga->xsize = GSS(mem+12); + tga->ysize = GSS(mem+14); + tga->pixsize = mem[16]; + tga->imgdes = mem[17]; + + if (tga->maptyp > 1) return(0); + switch (tga->imgtyp){ + case 1: /* raw cmap */ + case 2: /* raw rgb */ + case 3: /* raw b&w */ + case 9: /* cmap */ + case 10: /* rgb */ + case 11: /* b&w */ + break; + default: + return(0); + } + if (tga->mapsize && tga->mapbits > 32) return(0); + if (tga->xsize <= 0 || tga->xsize >= 4096) return(0); + if (tga->ysize <= 0 || tga->ysize >= 4096) return(0); + if (tga->pixsize > 32) return(0); + if (tga->pixsize == 0) return(0); + return(1); +} + +int imb_is_a_targa(void *buf) { + TARGA tga; + + return checktarga(&tga, buf); +} + +static void decodetarga(struct ImBuf *ibuf, unsigned char *mem, int psize) +/* struct ImBuf *ibuf; */ +/* uchar *mem; */ +/* int psize; */ +{ + int count, col, size; + unsigned int *rect; + uchar * cp = (uchar *) &col; + + if (ibuf == 0) return; + if (ibuf->rect == 0) return; + + size = ibuf->x * ibuf->y; + rect = ibuf->rect; + + /* alpha zetten */ + cp[0] = 0xff; + cp[1] = cp[2] = 0; + + while(size > 0){ + count = *mem++; + if (count >= 128) { + /*if (count == 128) printf("TARGA: 128 in file !\n");*/ + count -= 127; + + if (psize & 2){ + if (psize & 1){ + /* volgorde = bgra */ + cp[0] = mem[3]; + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ + mem += 4; + } else{ + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ + mem += 3; + } + } else{ + if (psize & 1){ + col = (mem[0] << 8) + mem[1]; + mem += 2; + } else{ + col = *mem++; + } + } + + size -= count; + if (size >= 0) { + while (count > 0) { + *rect++ = col; + count--; + } + } + } else{ + count ++; + size -= count; + if (size >= 0) { + while (count > 0){ + if (psize & 2){ + if (psize & 1){ + /* volgorde = bgra */ + cp[0] = mem[3]; + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ + mem += 4; + } else{ + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ + mem += 3; + } + } else{ + if (psize & 1){ + col = (mem[0] << 8) + mem[1]; + mem += 2; + } else{ + col = *mem++; + } + } + *rect++ = col; + count --; + } + } + } + } + if (size) printf("decodetarga: count would overwrite %d pixels\n", -size); +} + +static void ldtarga(struct ImBuf * ibuf,unsigned char * mem, int psize) +{ + int col,size; + unsigned int *rect; + uchar * cp = (uchar *) &col; + + if (ibuf == 0) return; + if (ibuf->rect == 0) return; + + size = ibuf->x * ibuf->y; + rect = ibuf->rect; + + /* alpha zetten */ + cp[0] = 0xff; + cp[1] = cp[2] = 0; + + while(size > 0){ + if (psize & 2){ + if (psize & 1){ + /* volgorde = bgra */ + cp[0] = mem[3]; + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + /*col = (mem[3] << 24) + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ + mem += 4; + } else{ + /* zet alpha bij 24 bits kleuren */ + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + /*col = 0xff000000 + (mem[0] << 16) + (mem[1] << 8) + mem[2];*/ + mem += 3; + } + } else{ + if (psize & 1){ + col = (mem[1] << 8) + mem[0]; + mem += 2; + } else{ + col = *mem++; + } + } + *rect++ = col; + size--; + } +} + + +struct ImBuf *imb_loadtarga(unsigned char *mem, int flags) +{ + TARGA tga; + struct ImBuf * ibuf; + int col, count, size; + unsigned int * rect; + uchar * cp = (uchar *) &col; + + if (checktarga(&tga,mem) == 0) return(0); + + if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize,0,0); + else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7,1,0); + + if (ibuf == 0) return(0); + ibuf->ftype = TGA; + ibuf->xorig = tga.xorig; + ibuf->yorig = tga.yorig; + mem = mem + 18 + tga.numid; + + cp[0] = 0xff; + cp[1] = cp[2] = 0; + + if (tga.mapsize){ + ibuf->mincol = tga.maporig; + ibuf->maxcol = tga.mapsize; + imb_addcmapImBuf(ibuf); + ibuf->cbits = 8; + for (count = 0 ; count < ibuf->maxcol ; count ++) { + switch (tga.mapbits >> 3) { + case 4: + cp[0] = mem[3]; + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + mem += 4; + break; + case 3: + cp[1] = mem[0]; + cp[2] = mem[1]; + cp[3] = mem[2]; + mem += 3; + break; + case 2: + col = (mem[1] << 8) + mem[0]; + mem += 2; + break; + case 1: + col = *mem++; + break; + } + ibuf->cmap[count] = col; + } + + size = 0; + for (col = ibuf->maxcol - 1; col > 0; col >>= 1) size++; + ibuf->depth = size; + + if (tga.mapbits != 32) { /* alpha bits zetten */ + ibuf->cmap[0] &= BIG_LONG(0x00ffffff); + } + } + + if (flags & IB_test) return (ibuf); + + if (tga.imgtyp != 1 && tga.imgtyp != 9) IMB_freecmapImBuf(ibuf); /* kan soms gebeuren (beuh) */ + + switch(tga.imgtyp){ + case 1: + case 2: + case 3: + if (tga.pixsize <= 8) ldtarga(ibuf,mem,0); + else if (tga.pixsize <= 16) ldtarga(ibuf,mem,1); + else if (tga.pixsize <= 24) ldtarga(ibuf,mem,2); + else if (tga.pixsize <= 32) ldtarga(ibuf,mem,3); + break; + case 9: + case 10: + case 11: + if (tga.pixsize <= 8) decodetarga(ibuf,mem,0); + else if (tga.pixsize <= 16) decodetarga(ibuf,mem,1); + else if (tga.pixsize <= 24) decodetarga(ibuf,mem,2); + else if (tga.pixsize <= 32) decodetarga(ibuf,mem,3); + break; + } + + if (ibuf->cmap){ + if ((flags & IB_cmap) == 0) IMB_applycmap(ibuf); + } + + if (tga.pixsize == 16 && ibuf->cmap == 0){ + rect = ibuf->rect; + for (size = ibuf->x * ibuf->y; size > 0; size --){ + col = *rect; + col = ((col & 0x1f) << 19) + ((col & 0x3e0) << 6) + ((col & 0x7c00) >> 7) ; + col += (col & 0xe0e0e0) >> 5; + *rect++ = col + 0xff000000; + } + ibuf->depth = 24; + } + + if (tga.imgtyp == 3 || tga.imgtyp == 11){ + uchar *crect; + unsigned int *lrect, col; + + crect = (uchar *) ibuf->rect; + lrect = (unsigned int *) ibuf->rect; + + for (size = ibuf->x * ibuf->y; size > 0; size --){ + col = *lrect++; + + crect[0] = 255; + crect[1] = crect[2] = crect[3] = col; + crect += 4; + } + } + + if (flags & IB_ttob) tga.imgdes ^= 0x20; + if (tga.imgdes & 0x20) IMB_flipy(ibuf); + + if (ibuf) { + if (ibuf->rect && (flags & IB_cmap)==0) + IMB_convert_rgba_to_abgr((ibuf->x+ibuf->skipx)*ibuf->y, ibuf->rect); + } + + return(ibuf); +} diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c new file mode 100644 index 00000000000..52a29217bef --- /dev/null +++ b/source/blender/imbuf/intern/util.c @@ -0,0 +1,90 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * util.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_targa.h" +#include "IMB_png.h" + +/* from misc_util: flip the bytes from x */ +#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) + +/* this one is only def-ed once, strangely... */ +#define GSS(x) (((uchar *)(x))[1] << 8 | ((uchar *)(x))[0]) + +int IMB_ispic(char *name) +{ + struct stat st; + int fp, buf[10]; + int ofs = 0; + + if (ib_stat(name,&st) == -1) return(0); + if (((st.st_mode) & S_IFMT) == S_IFREG){ + if ((fp = open(name,O_BINARY|O_RDONLY)) >= 0){ + if (read(fp,buf,32)==32){ + close(fp); + if (buf[ofs] == CAT) ofs += 3; + if (buf[ofs] == FORM){ + if (buf[ofs + 2] == ILBM) return(AMI); + if (buf[ofs + 2] == ANIM){ + if (buf[ofs + 3] == FORM){ + return(ANIM); + }else{ + return(Anim); + } + } + } else { + if (GS(buf) == IMAGIC) return(IMAGIC); + if (GSS(buf) == IMAGIC) return(IMAGIC); + if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0) return(JPG); + + /* at windows there are ".ffl" files with the same magic numnber... + besides that, tim images are not really important anymore! */ + /* if ((BIG_LONG(buf[0]) == 0x10000000) && ((BIG_LONG(buf[1]) & 0xf0ffffff) == 0)) return(TIM); */ + + } + if (imb_is_a_png(buf)) return(PNG); + if (imb_is_a_targa(buf)) return(TGA); + return(FALSE); + } + close(fp); + } + } + return(FALSE); +} diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c new file mode 100644 index 00000000000..e4d24097760 --- /dev/null +++ b/source/blender/imbuf/intern/writeimage.c @@ -0,0 +1,145 @@ +/** + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * writeimage.c + * + * $Id$ + */ + +#include "BLI_blenlib.h" + +#include "imbuf.h" +#include "imbuf_patch.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" + +#include "IMB_targa.h" +#include "IMB_jpeg.h" +#include "IMB_iris.h" +#include "IMB_ham.h" +#include "IMB_hamx.h" +#include "IMB_amiga.h" + +#include "IMB_iff.h" +#include "IMB_bitplanes.h" +#include "IMB_divers.h" + + +short (*IMB_fp_png_encode)(struct ImBuf *ibuf, int file, int flags) = 0; + +short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags) +{ + short ok=TRUE,delpl=FALSE; + int file = -1; + + if (ibuf==0) return (FALSE); + ibuf->flags = flags; + + if (IS_jpg(ibuf)) { + if (imb_save_jpeg(naam, ibuf, flags)) return (0); + else return (TRUE); + } + file = open(naam, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); + if (file < 0) return (FALSE); + + if (flags & IB_rect){ + if (ibuf->cmap){ + imb_checkncols(ibuf); + } + } + + if (IS_png(ibuf) && IMB_fp_png_encode) { + ok = IMB_fp_png_encode(ibuf,file,flags); + if (ok) { + close (file); + return (ok); + } + } + + if (IS_tga(ibuf) || IS_png(ibuf)) { + ok = imb_savetarga(ibuf,file,flags); + if (ok) { + close (file); + return (ok); + } + } + + if (IS_iris(ibuf)) { + ok = imb_saveiris(ibuf,file,flags); + if (ok) { + close (file); + return (ok); + } + } + + if (ok) ok = imb_start_iff(ibuf,file); + + if (IS_amiga(ibuf)){ + IMB_flipy(ibuf); + if (flags & IB_rect){ + if ((flags & IB_cmap) == 0) { + if (IS_ham(ibuf)){ + if (ok) ok = imb_converttoham(ibuf); + }else if (ibuf->cmap){ + if (ok) ok = IMB_converttocmap(ibuf); + } + } + if (ok){ + if (ibuf->planes==0){ + delpl=TRUE; + ok=imb_addplanesImBuf(ibuf); + } + imb_longtobp(ibuf); + } + } + + if (flags & IB_vert){ + if (ok) ok = imb_encodebodyv(ibuf,file); + } + else{ + if (ok) ok = imb_encodebodyh(ibuf,file); + } + if (ok) ok = imb_update_iff(file,BODY); + }else if (IS_anim(ibuf)) { + if (ok) ok = imb_enc_anim(ibuf, file); + if (ok) ok = imb_update_iff(file, BODY); + } + close(file); + + if (ok==FALSE) { + fprintf(stderr,"Couldn't save picture.\n"); + } + if (delpl) imb_freeplanesImBuf(ibuf); + + return (ok); +} + |