Added libgd

This commit is contained in:
Sergii Pylypenko
2017-11-22 15:45:06 +02:00
parent 66f7cc1cfd
commit 374dbd86b3
69 changed files with 51866 additions and 0 deletions

16
project/jni/gd/Android.mk Normal file
View File

@@ -0,0 +1,16 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := gd
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/src $(LOCAL_PATH)/../png/include $(LOCAL_PATH)/../jpeg/include
LOCAL_CFLAGS := -O3 -DHAVE_CONFIG_H
LOCAL_CPP_EXTENSION := .cpp
LOCAL_SRC_FILES := $(addprefix src/, $(notdir $(wildcard $(LOCAL_PATH)/src/*.c) $(wildcard $(LOCAL_PATH)/src/*.cpp)))
LOCAL_STATIC_LIBRARIES :=
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,72 @@
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [2.2.5] - 2017-08-30
### Security
- Double-free in gdImagePngPtr(). (CVE-2017-6362)
- Buffer over-read into uninitialized memory. (CVE-2017-7890)
### Fixed
- Fix #109: XBM reading fails with printed error
- Fix #338: Fatal and normal libjpeg/ibpng errors not distinguishable
- Fix #357: 2.2.4: Segfault in test suite
- Fix #386: gdImageGrayScale() may produce colors
- Fix #406: webpng -i removes the transparent color
- Fix Coverity #155475: Failure to restore alphaBlendingFlag
- Fix Coverity #155476: potential resource leak
- Fix several build issues and test failures
- Fix and reenable optimized support for reading 1 bps TIFFs
### Added
- The native MSVC buildchain now supports libtiff and most executables
## [2.2.4] - 2017-01-18
### Security
- gdImageCreate() doesn't check for oversized images and as such is
prone to DoS vulnerabilities. (CVE-2016-9317)
- double-free in gdImageWebPtr() (CVE-2016-6912)
- potential unsigned underflow in gd_interpolation.c
- DOS vulnerability in gdImageCreateFromGd2Ctx()
### Fixed
- Fix #354: Signed Integer Overflow gd_io.c
- Fix #340: System frozen
- Fix OOB reads of the TGA decompression buffer
- Fix DOS vulnerability in gdImageCreateFromGd2Ctx()
- Fix potential unsigned underflow
- Fix double-free in gdImageWebPtr()
- Fix invalid read in gdImageCreateFromTiffPtr()
- Fix OOB reads of the TGA decompression buffer
- Fix #68: gif: buffer underflow reported by AddressSanitizer
- Avoid potentially dangerous signed to unsigned conversion
- Fix #304: test suite failure in gif/bug00006 [2.2.3]
- Fix #329: GD_BILINEAR_FIXED gdImageScale() can cause black border
- Fix #330: Integer overflow in gdImageScaleBilinearPalette()
- Fix 321: Null pointer dereferences in gdImageRotateInterpolated
- Fix whitespace and add missing comment block
- Fix #319: gdImageRotateInterpolated can have wrong background color
- Fix color quantization documentation
- Fix #309: gdImageGd2() writes wrong chunk sizes on boundaries
- Fix #307: GD_QUANT_NEUQUANT fails to unset trueColor flag
- Fix #300: gdImageClone() assigns res_y = res_x
- Fix #299: Regression regarding gdImageRectangle() with gdImageSetThickness()
- Replace GNU old-style field designators with C89 compatible initializers
- Fix #297: gdImageCrop() converts palette image to truecolor image
- Fix #290: TGA RLE decoding is broken
- Fix unnecessary non NULL checks
- Fix #289: Passing unrecognized formats to gdImageGd2 results in corrupted files
- Fix #280: gdImageWebpEx() `quantization` parameter is a misnomer
- Publish all gdImageCreateFromWebp*() functions and gdImageWebpCtx()
- Fix issue #276: Sometimes pixels are missing when storing images as BMPs
- Fix issue #275: gdImageBmpCtx() may segfault for non-seekable contexts
- Fix copy&paste error in gdImageScaleBicubicFixed()
### Added
- More documentation
- Documentation on GD and GD2 formats
- More tests

View File

@@ -0,0 +1,26 @@
chapg
Chris Reuter
Colin Watson
Dimitar Dobrev
edink
Gilles Espinasse
guenter
Kornel Lesiński
kshepherd
lhecking
Marcin Wojdyr
mattias
Mike Frysinger
mloskot
Nathanael Jones
nlopess
Ondřej Surý
Pierre Joye
pornel
Remi Collet
scottmac
tabe
Takeshi Abe
Tim Toohey
tostercx
Vincent Bernat

73
project/jni/gd/COPYING Normal file
View File

@@ -0,0 +1,73 @@
Credits and license terms:
In order to resolve any possible confusion regarding the authorship of
gd, the following copyright statement covers all of the authors who
have required such a statement. If you are aware of any oversights in
this copyright notice, please contact Pierre-A. Joye who will be
pleased to correct them.
* Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under
Grant P41-RR02188 by the National Institutes of Health.
* Portions copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004 by Boutell.Com, Inc.
* Portions relating to GD2 format copyright 1999, 2000, 2001, 2002,
2003, 2004 Philip Warner.
* Portions relating to PNG copyright 1999, 2000, 2001, 2002, 2003,
2004 Greg Roelofs.
* Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002,
2003, 2004 John Ellson (ellson@graphviz.org).
* Portions relating to gdft.c copyright 2001, 2002, 2003, 2004 John
Ellson (ellson@graphviz.org).
* Portions copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Pierre-Alain Joye (pierre@libgd.org).
* Portions relating to JPEG and to color quantization copyright
2000, 2001, 2002, 2003, 2004, Doug Becker and copyright (C) 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Thomas
G. Lane. This software is based in part on the work of the
Independent JPEG Group. See the file README-JPEG.TXT for more
information.
* Portions relating to GIF compression copyright 1989 by Jef
Poskanzer and David Rowley, with modifications for thread safety
by Thomas Boutell.
* Portions relating to GIF decompression copyright 1990, 1991, 1993
by David Koblas, with modifications for thread safety by Thomas
Boutell.
* Portions relating to WBMP copyright 2000, 2001, 2002, 2003, 2004
Maurice Szmurlo and Johan Van den Brande.
* Portions relating to GIF animations copyright 2004 Jaakko Hyvätti
(jaakko.hyvatti@iki.fi)
Permission has been granted to copy, distribute and modify gd in
any context without fee, including a commercial application,
provided that this notice is present in user-accessible supporting
documentation.
This does not affect your ownership of the derived work itself,
and the intent is to assure proper credit for the authors of gd,
not to interfere with your productive use of gd. If you have
questions, ask. "Derived works" includes all programs that utilize
the library. Credit must be given in user-accessible
documentation.
This software is provided "AS IS." The copyright holders disclaim
all warranties, either express or implied, including but not
limited to implied warranties of merchantability and fitness for a
particular purpose, with respect to this code and accompanying
documentation.
Although their code does not appear in the current release, the
authors wish to thank David Koblas, David Rowley, and Hutchison
Avenue Software Corporation for their prior contributions.

41
project/jni/gd/README.md Normal file
View File

@@ -0,0 +1,41 @@
# GD Graphics (Draw) Library
[![Build Status](https://travis-ci.org/libgd/libgd.svg?branch=master)](https://travis-ci.org/libgd/libgd)
[![Build Status](https://scan.coverity.com/projects/3810/badge.svg)](https://scan.coverity.com/projects/libgd)
GD is an open source code library for the dynamic creation of images by
programmers.
GD is written in C, and "wrappers" are available for Perl, PHP and other
languages. GD can read and write many different image formats. GD is commonly
used to generate charts, graphics, thumbnails, and most anything else, on the
fly.
The most common applications of GD involve website development, although it
can be used with any standalone application!
The library was originally developed by Thomas Boutell and is now maintained
by many contributors (see the [CONTRIBUTORS](CONTRIBUTORS) file) under the
umbrella of PHP.net.
## Downloads/etc...
Please visit our [homepage](http://www.libgd.org/) for more details.
## Supported Image Formats
GD has builtin support for:
* [BMP](https://en.wikipedia.org/wiki/BMP_file_format)
* [GIF](https://en.wikipedia.org/wiki/GIF)
* [TGA](https://en.wikipedia.org/wiki/Truevision_TGA)
* [WBMP](https://en.wikipedia.org/wiki/Wireless_Application_Protocol_Bitmap_Format)
It also has optional support for more formats via external libraries:
* [JPEG](https://en.wikipedia.org/wiki/JPEG) via [IJG/libjpeg](http://www.ijg.org/) or [libjpeg-turbo](http://libjpeg-turbo.virtualgl.org/)
* Does not include [JPEG 2000](https://en.wikipedia.org/wiki/JPEG_2000)
* [PNG](https://en.wikipedia.org/wiki/Portable_Network_Graphics) via [libpng](http://www.libpng.org/)
* [TIFF](https://en.wikipedia.org/wiki/Tagged_Image_File_Format) via [libtiff](http://www.remotesensing.org/libtiff/)
* [WebP](https://en.wikipedia.org/wiki/WebP) via [libwebp](https://developers.google.com/speed/webp/)
* [XPM](https://en.wikipedia.org/wiki/X_PixMap) via [libXpm](http://xorg.freedesktop.org/)

View File

@@ -0,0 +1,277 @@
/*
* Generated file - do not edit directly.
*
* This file was generated from:
* http://www.w3.org/TR/REC-html40/sgml/entities.html
* by means of the script:
* entities.tcl
*/
#ifdef __cplusplus
extern "C" {
#endif
static struct entities_s {
char *name;
int value;
} entities[] = {
{"AElig", 198},
{"Aacute", 193},
{"Acirc", 194},
{"Agrave", 192},
{"Alpha", 913},
{"Aring", 197},
{"Atilde", 195},
{"Auml", 196},
{"Beta", 914},
{"Ccedil", 199},
{"Chi", 935},
{"Dagger", 8225},
{"Delta", 916},
{"ETH", 208},
{"Eacute", 201},
{"Ecirc", 202},
{"Egrave", 200},
{"Epsilon", 917},
{"Eta", 919},
{"Euml", 203},
{"Gamma", 915},
{"Iacute", 205},
{"Icirc", 206},
{"Igrave", 204},
{"Iota", 921},
{"Iuml", 207},
{"Kappa", 922},
{"Lambda", 923},
{"Mu", 924},
{"Ntilde", 209},
{"Nu", 925},
{"OElig", 338},
{"Oacute", 211},
{"Ocirc", 212},
{"Ograve", 210},
{"Omega", 937},
{"Omicron", 927},
{"Oslash", 216},
{"Otilde", 213},
{"Ouml", 214},
{"Phi", 934},
{"Pi", 928},
{"Prime", 8243},
{"Psi", 936},
{"Rho", 929},
{"Scaron", 352},
{"Sigma", 931},
{"THORN", 222},
{"Tau", 932},
{"Theta", 920},
{"Uacute", 218},
{"Ucirc", 219},
{"Ugrave", 217},
{"Upsilon", 933},
{"Uuml", 220},
{"Xi", 926},
{"Yacute", 221},
{"Yuml", 376},
{"Zeta", 918},
{"aacute", 225},
{"acirc", 226},
{"acute", 180},
{"aelig", 230},
{"agrave", 224},
{"alefsym", 8501},
{"alpha", 945},
{"amp", 38},
{"and", 8743},
{"ang", 8736},
{"aring", 229},
{"asymp", 8776},
{"atilde", 227},
{"auml", 228},
{"bdquo", 8222},
{"beta", 946},
{"brvbar", 166},
{"bull", 8226},
{"cap", 8745},
{"ccedil", 231},
{"cedil", 184},
{"cent", 162},
{"chi", 967},
{"circ", 710},
{"clubs", 9827},
{"cong", 8773},
{"copy", 169},
{"crarr", 8629},
{"cup", 8746},
{"curren", 164},
{"dArr", 8659},
{"dagger", 8224},
{"darr", 8595},
{"deg", 176},
{"delta", 948},
{"diams", 9830},
{"divide", 247},
{"eacute", 233},
{"ecirc", 234},
{"egrave", 232},
{"empty", 8709},
{"emsp", 8195},
{"ensp", 8194},
{"epsilon", 949},
{"equiv", 8801},
{"eta", 951},
{"eth", 240},
{"euml", 235},
{"euro", 8364},
{"exist", 8707},
{"fnof", 402},
{"forall", 8704},
{"frac12", 189},
{"frac14", 188},
{"frac34", 190},
{"frasl", 8260},
{"gamma", 947},
{"ge", 8805},
{"gt", 62},
{"hArr", 8660},
{"harr", 8596},
{"hearts", 9829},
{"hellip", 8230},
{"iacute", 237},
{"icirc", 238},
{"iexcl", 161},
{"igrave", 236},
{"image", 8465},
{"infin", 8734},
{"int", 8747},
{"iota", 953},
{"iquest", 191},
{"isin", 8712},
{"iuml", 239},
{"kappa", 954},
{"lArr", 8656},
{"lambda", 955},
{"lang", 9001},
{"laquo", 171},
{"larr", 8592},
{"lceil", 8968},
{"ldquo", 8220},
{"le", 8804},
{"lfloor", 8970},
{"lowast", 8727},
{"loz", 9674},
{"lrm", 8206},
{"lsaquo", 8249},
{"lsquo", 8216},
{"lt", 60},
{"macr", 175},
{"mdash", 8212},
{"micro", 181},
{"middot", 183},
{"minus", 8722},
{"mu", 956},
{"nabla", 8711},
{"nbsp", 160},
{"ndash", 8211},
{"ne", 8800},
{"ni", 8715},
{"not", 172},
{"notin", 8713},
{"nsub", 8836},
{"ntilde", 241},
{"nu", 957},
{"oacute", 243},
{"ocirc", 244},
{"oelig", 339},
{"ograve", 242},
{"oline", 8254},
{"omega", 969},
{"omicron", 959},
{"oplus", 8853},
{"or", 8744},
{"ordf", 170},
{"ordm", 186},
{"oslash", 248},
{"otilde", 245},
{"otimes", 8855},
{"ouml", 246},
{"para", 182},
{"part", 8706},
{"permil", 8240},
{"perp", 8869},
{"phi", 966},
{"pi", 960},
{"piv", 982},
{"plusmn", 177},
{"pound", 163},
{"prime", 8242},
{"prod", 8719},
{"prop", 8733},
{"psi", 968},
{"quot", 34},
{"rArr", 8658},
{"radic", 8730},
{"rang", 9002},
{"raquo", 187},
{"rarr", 8594},
{"rceil", 8969},
{"rdquo", 8221},
{"real", 8476},
{"reg", 174},
{"rfloor", 8971},
{"rho", 961},
{"rlm", 8207},
{"rsaquo", 8250},
{"rsquo", 8217},
{"sbquo", 8218},
{"scaron", 353},
{"sdot", 8901},
{"sect", 167},
{"shy", 173},
{"sigma", 963},
{"sigmaf", 962},
{"sim", 8764},
{"spades", 9824},
{"sub", 8834},
{"sube", 8838},
{"sum", 8721},
{"sup", 8835},
{"sup1", 185},
{"sup2", 178},
{"sup3", 179},
{"supe", 8839},
{"szlig", 223},
{"tau", 964},
{"there4", 8756},
{"theta", 952},
{"thetasym", 977},
{"thinsp", 8201},
{"thorn", 254},
{"tilde", 732},
{"times", 215},
{"trade", 8482},
{"uArr", 8657},
{"uacute", 250},
{"uarr", 8593},
{"ucirc", 251},
{"ugrave", 249},
{"uml", 168},
{"upsih", 978},
{"upsilon", 965},
{"uuml", 252},
{"weierp", 8472},
{"xi", 958},
{"yacute", 253},
{"yen", 165},
{"yuml", 255},
{"zeta", 950},
{"zwj", 8205},
{"zwnj", 8204},
};
#define ENTITY_NAME_LENGTH_MAX 8
#define NR_OF_ENTITIES 252
#ifdef __cplusplus
}
#endif

1649
project/jni/gd/include/gd.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
#ifndef GD_COLOR_MAP_H
#define GD_COLOR_MAP_H 1
#include "gd.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
char *color_name;
int red;
int green;
int blue;
} gdColorMapEntry;
typedef struct {
int num_entries;
gdColorMapEntry *entries;
} gdColorMap;
extern BGD_EXPORT_DATA_PROT gdColorMap GD_COLOR_MAP_X11;
BGD_DECLARE(int) gdColorMapLookup(const gdColorMap color_map, const char *color_name, int *r, int *g, int *b);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,46 @@
#ifndef GD_ERRORS_H
#define GD_ERRORS_H
#ifndef _WIN32
# include <syslog.h>
#else
/*
* priorities/facilities are encoded into a single 32-bit quantity, where the
* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
* (0-big number). Both the priorities and the facilities map roughly
* one-to-one to strings in the syslogd(8) source code. This mapping is
* included in this file.
*
* priorities (these are ordered)
*/
# define LOG_EMERG 0 /* system is unusable */
# define LOG_ALERT 1 /* action must be taken immediately */
# define LOG_CRIT 2 /* critical conditions */
# define LOG_ERR 3 /* error conditions */
# define LOG_WARNING 4 /* warning conditions */
# define LOG_NOTICE 5 /* normal but significant condition */
# define LOG_INFO 6 /* informational */
# define LOG_DEBUG 7 /* debug-level messages */
#endif
/*
LOG_EMERG system is unusable
LOG_ALERT action must be taken immediately
LOG_CRIT critical conditions
LOG_ERR error conditions
LOG_WARNING warning conditions
LOG_NOTICE normal, but significant, condition
LOG_INFO informational message
LOG_DEBUG debug-level message
*/
#define GD_ERROR LOG_ERR
#define GD_WARNING LOG_WARNING
#define GD_NOTICE LOG_NOTICE
#define GD_INFO LOG_INFO
#define GD_DEBUG LOG_DEBUG
void gd_error(const char *format, ...);
void gd_error_ex(int priority, const char *format, ...);
#endif

View File

@@ -0,0 +1,100 @@
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GD_IO_H
#define GD_IO_H 1
#include <stdio.h>
#ifdef VMS
# define Putchar gdPutchar
#endif
/*
Group: Types
typedef: gdIOCtx
gdIOCtx structures hold function pointers for doing image IO.
Most of the gd functions that read and write files, such as
<gdImagePng> also have variants that accept a <gdIOCtx> structure;
see <gdImagePngCtx> and <gdImageCreateFromJpegCtx>.
Those who wish to provide their own custom routines to read and
write images can populate a gdIOCtx structure with functions of
their own devising to to read and write data. For image reading, the
only mandatory functions are getC and getBuf, which must return the
number of characters actually read, or a negative value on error or
EOF. These functions must read the number of characters requested
unless at the end of the file.
For image writing, the only mandatory functions are putC and putBuf,
which return the number of characters written; these functions must
write the number of characters requested except in the event of an
error. The seek and tell functions are only required in conjunction
with the gd2 file format, which supports quick loading of partial
images. The gd_free function will not be invoked when calling the
standard Ctx functions; it is an implementation convenience when
adding new data types to gd. For examples, see gd_png.c, gd_gd2.c,
gd_jpeg.c, etc., all of which rely on gdIOCtx to implement the
standard image read and write functions.
> typedef struct gdIOCtx
> {
> int (*getC) (struct gdIOCtx *);
> int (*getBuf) (struct gdIOCtx *, void *, int wanted);
>
> void (*putC) (struct gdIOCtx *, int);
> int (*putBuf) (struct gdIOCtx *, const void *, int wanted);
>
> // seek must return 1 on SUCCESS, 0 on FAILURE. Unlike fseek!
> int (*seek) (struct gdIOCtx *, const int);
> long (*tell) (struct gdIOCtx *);
>
> void (*gd_free) (struct gdIOCtx *);
> } gdIOCtx;
*/
typedef struct gdIOCtx {
int (*getC)(struct gdIOCtx *);
int (*getBuf)(struct gdIOCtx *, void *, int);
void (*putC)(struct gdIOCtx *, int);
int (*putBuf)(struct gdIOCtx *, const void *, int);
/* seek must return 1 on SUCCESS, 0 on FAILURE. Unlike fseek! */
int (*seek)(struct gdIOCtx *, const int);
long (*tell)(struct gdIOCtx *);
void (*gd_free)(struct gdIOCtx *);
void *data;
} gdIOCtx;
typedef struct gdIOCtx *gdIOCtxPtr;
void Putword(int w, gdIOCtx *ctx);
void Putchar(int c, gdIOCtx *ctx);
void gdPutC(const unsigned char c, gdIOCtx *ctx);
int gdPutBuf(const void *, int, gdIOCtx *);
void gdPutWord(int w, gdIOCtx *ctx);
void gdPutInt(int w, gdIOCtx *ctx);
int gdGetC(gdIOCtx *ctx);
int gdGetBuf(void *, int, gdIOCtx *);
int gdGetByte(int *result, gdIOCtx *ctx);
int gdGetWord(int *result, gdIOCtx *ctx);
int gdGetWordLSB(signed short int *result, gdIOCtx *ctx);
int gdGetInt(int *result, gdIOCtx *ctx);
int gdGetIntLSB(signed int *result, gdIOCtx *ctx);
int gdSeek(gdIOCtx *ctx, const int offset);
long gdTell(gdIOCtx *ctx);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,88 @@
#ifdef __cplusplus
extern "C" {
#endif
/*
* gdcache.h
*
* Caches of pointers to user structs in which the least-recently-used
* element is replaced in the event of a cache miss after the cache has
* reached a given size.
*
* John Ellson (ellson@graphviz.org) Oct 31, 1997
*
* Test this with:
* gcc -o gdcache -g -Wall -DTEST gdcache.c
*
* The cache is implemented by a singly-linked list of elements
* each containing a pointer to a user struct that is being managed by
* the cache.
*
* The head structure has a pointer to the most-recently-used
* element, and elements are moved to this position in the list each
* time they are used. The head also contains pointers to three
* user defined functions:
* - a function to test if a cached userdata matches some keydata
* - a function to provide a new userdata struct to the cache
* if there has been a cache miss.
* - a function to release a userdata struct when it is
* no longer being managed by the cache
*
* In the event of a cache miss the cache is allowed to grow up to
* a specified maximum size. After the maximum size is reached then
* the least-recently-used element is discarded to make room for the
* new. The most-recently-returned value is always left at the
* beginning of the list after retrieval.
*
* In the current implementation the cache is traversed by a linear
* search from most-recent to least-recent. This linear search
* probably limits the usefulness of this implementation to cache
* sizes of a few tens of elements.
*/
/*********************************************************/
/* header */
/*********************************************************/
#include <stdlib.h>
#ifndef NULL
# define NULL (void *)0
#endif
/* user defined function templates */
typedef int (*gdCacheTestFn_t)(void *userdata, void *keydata);
typedef void *(*gdCacheFetchFn_t)(char **error, void *keydata);
typedef void (*gdCacheReleaseFn_t)(void *userdata);
/* element structure */
typedef struct gdCache_element_s gdCache_element_t;
struct gdCache_element_s {
gdCache_element_t *next;
void *userdata;
};
/* head structure */
typedef struct gdCache_head_s gdCache_head_t;
struct gdCache_head_s {
gdCache_element_t *mru;
int size;
char *error;
gdCacheTestFn_t gdCacheTest;
gdCacheFetchFn_t gdCacheFetch;
gdCacheReleaseFn_t gdCacheRelease;
};
/* function templates */
gdCache_head_t *gdCacheCreate(int size,
gdCacheTestFn_t gdCacheTest,
gdCacheFetchFn_t gdCacheFetch,
gdCacheReleaseFn_t gdCacheRelease
);
void gdCacheDelete(gdCache_head_t *head);
void *gdCacheGet(gdCache_head_t *head, void *keydata);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,28 @@
#ifndef _GDFONTG_H_
#define _GDFONTG_H_ 1
#ifdef __cplusplus
extern "C"
{
#endif
/*
This is a header file for gd font, generated using
bdftogd version 0.51 by Jan Pazdziora, adelton@fi.muni.cz
from bdf font
-Misc-Fixed-Bold-R-Normal-Sans-15-140-75-75-C-90-ISO8859-2
at Mon Jan 26 14:45:58 1998.
The original bdf was holding following copyright:
"Libor Skarvada, libor@informatics.muni.cz"
*/
#include "gd.h"
extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontGiant;
BGD_DECLARE(gdFontPtr) gdFontGetGiant(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,29 @@
#ifndef _GDFONTL_H_
#define _GDFONTL_H_ 1
#ifdef __cplusplus
extern "C"
{
#endif
/*
This is a header file for gd font, generated using
bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
from bdf font
-misc-fixed-medium-r-normal--16-140-75-75-c-80-iso8859-2
at Tue Jan 6 19:39:27 1998.
The original bdf was holding following copyright:
"Libor Skarvada, libor@informatics.muni.cz"
*/
#include "gd.h"
extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontLarge;
BGD_DECLARE(gdFontPtr) gdFontGetLarge(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,27 @@
#ifndef _GDFONTMB_H_
#define _GDFONTMB_H_ 1
#ifdef __cplusplus
extern "C"
{
#endif
/*
This is a header file for gd font, generated using
bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
from bdf font
-misc-fixed-bold-r-normal-sans-13-94-100-100-c-70-iso8859-2
at Thu Jan 8 13:54:57 1998.
No copyright info was found in the original bdf.
*/
#include "gd.h"
extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontMediumBold;
BGD_DECLARE(gdFontPtr) gdFontGetMediumBold(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,27 @@
#ifndef _GDFONTS_H_
#define _GDFONTS_H_ 1
#ifdef __cplusplus
extern "C"
{
#endif
/*
This is a header file for gd font, generated using
bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
from bdf font
-misc-fixed-medium-r-semicondensed-sans-12-116-75-75-c-60-iso8859-2
at Thu Jan 8 14:13:20 1998.
No copyright info was found in the original bdf.
*/
#include "gd.h"
extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontSmall;
BGD_DECLARE(gdFontPtr) gdFontGetSmall(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,28 @@
#ifndef _GDFONTT_H_
#define _GDFONTT_H_ 1
#ifdef __cplusplus
extern "C"
{
#endif
/*
This is a header file for gd font, generated using
bdftogd version 0.5 by Jan Pazdziora, adelton@fi.muni.cz
from bdf font
-Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-2
at Thu Jan 8 13:49:54 1998.
The original bdf was holding following copyright:
"Libor Skarvada, libor@informatics.muni.cz"
*/
#include "gd.h"
extern BGD_EXPORT_DATA_PROT gdFontPtr gdFontTiny;
BGD_DECLARE(gdFontPtr) gdFontGetTiny(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,30 @@
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GDFX_H
#define GDFX_H 1
BGD_DECLARE(gdImagePtr) gdImageSquareToCircle(gdImagePtr im, int radius);
BGD_DECLARE(char *) gdImageStringFTCircle(
gdImagePtr im,
int cx,
int cy,
double radius,
double textRadius,
double fillPortion,
char *font,
double points,
char *top,
char *bottom,
int fgcolor);
BGD_DECLARE(void) gdImageSharpen (gdImagePtr im, int pct);
#endif /* GDFX_H */
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

112
project/jni/gd/src/bmp.h Normal file
View File

@@ -0,0 +1,112 @@
/* $Id$ */
#ifdef __cplusplus
extern "C" {
#endif
/*
gd_bmp.c
Bitmap format support for libgd
* Written 2007, Scott MacVicar
---------------------------------------------------------------------------
Todo:
RLE4, RLE8 and Bitfield encoding
Add full support for Windows v4 and Windows v5 header formats
----------------------------------------------------------------------------
*/
#ifndef BMP_H
#define BMP_H 1
#define BMP_PALETTE_3 1
#define BMP_PALETTE_4 2
#define BMP_WINDOWS_V3 40
#define BMP_OS2_V1 12
#define BMP_OS2_V2 64
#define BMP_WINDOWS_V4 108
#define BMP_WINDOWS_V5 124
#define BMP_BI_RGB 0
#define BMP_BI_RLE8 1
#define BMP_BI_RLE4 2
#define BMP_BI_BITFIELDS 3
#define BMP_BI_JPEG 4
#define BMP_BI_PNG 5
#define BMP_RLE_COMMAND 0
#define BMP_RLE_ENDOFLINE 0
#define BMP_RLE_ENDOFBITMAP 1
#define BMP_RLE_DELTA 2
#define BMP_RLE_TYPE_RAW 0
#define BMP_RLE_TYPE_RLE 1
/* BMP header. */
typedef struct {
/* 16 bit - header identifying the type */
signed short int magic;
/* 32bit - size of the file */
int size;
/* 16bit - these two are in the spec but "reserved" */
signed short int reserved1;
signed short int reserved2;
/* 32 bit - offset of the bitmap header from data in bytes */
signed int off;
} bmp_hdr_t;
/* BMP info. */
typedef struct {
/* 16bit - Type, ie Windows or OS/2 for the palette info */
signed short int type;
/* 32bit - The length of the bitmap information header in bytes. */
signed int len;
/* 32bit - The width of the bitmap in pixels. */
signed int width;
/* 32bit - The height of the bitmap in pixels. */
signed int height;
/* 8 bit - The bitmap data is specified in top-down order. */
signed char topdown;
/* 16 bit - The number of planes. This must be set to a value of one. */
signed short int numplanes;
/* 16 bit - The number of bits per pixel. */
signed short int depth;
/* 32bit - The type of compression used. */
signed int enctype;
/* 32bit - The size of the image in bytes. */
signed int size;
/* 32bit - The horizontal resolution in pixels/metre. */
signed int hres;
/* 32bit - The vertical resolution in pixels/metre. */
signed int vres;
/* 32bit - The number of color indices used by the bitmap. */
signed int numcolors;
/* 32bit - The number of color indices important for displaying the bitmap. */
signed int mincolors;
} bmp_info_t;
#endif
#ifdef __cplusplus
}
#endif

139
project/jni/gd/src/config.h Normal file
View File

@@ -0,0 +1,139 @@
/* src/config.h. Generated from config.hin by configure. */
/* src/config.hin. Generated from configure.ac by autoheader. */
/* Define is you are building for Win32 API */
/* #undef BGDWIN32 */
/* Define to 1 if you have the <dirent.h> header file. */
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the ft2build.h header. */
//#define HAVE_FT2BUILD_H 1
/* Define if you have the iconv() function and it works. */
//#define HAVE_ICONV 1
/* Define to 1 if you have the <iconv.h> header file. */
//#define HAVE_ICONV_H 1
/* Define if <iconv.h> defines iconv_t. */
//#define HAVE_ICONV_T_DEF 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have fontconfig */
//#define HAVE_LIBFONTCONFIG 1
/* Define if you have freetype */
//#define HAVE_LIBFREETYPE 1
/* Define if you have liq */
/* #undef HAVE_LIBIMAGEQUANT */
/* Define if you have jpeg */
#define HAVE_LIBJPEG 1
/* Define to 1 if you have the `m' library (-lm). */
#define HAVE_LIBM 1
/* Define if you have png */
#define HAVE_LIBPNG 1
/* Define if you have tiff */
//#define HAVE_LIBTIFF 1
/* Define if you have webp */
//#define HAVE_LIBWEBP 1
/* Define if you have xpm */
//#define HAVE_LIBXPM 1
/* Define if you have zlib */
#define HAVE_LIBZ 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if OpenMP is enabled */
//#define HAVE_OPENMP 1
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Have PTHREAD_PRIO_INHERIT. */
//#define HAVE_PTHREAD_PRIO_INHERIT 1
/* Define to 1 if you have the <stddef.h> header file. */
#define HAVE_STDDEF_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 or 0, depending whether the compiler supports simple visibility
declarations. */
#define HAVE_VISIBILITY 1
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libgd"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "https://github.com/libgd/libgd/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "GD"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "GD 2.2.5"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libgd"
/* Define to the home page for this package. */
#define PACKAGE_URL "http://lib.gd"
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.2.5"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "2.2.5"

4539
project/jni/gd/src/gd.c Normal file

File diff suppressed because it is too large Load Diff

1142
project/jni/gd/src/gd_bmp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gd.h"
#include "gd_color.h"
/**
* The threshold method works relatively well but it can be improved.
* Maybe L*a*b* and Delta-E will give better results (and a better
* granularity).
*/
int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold)
{
const int dr = gdImageRed(im, col1) - gdImageRed(im, col2);
const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2);
const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2);
const int da = gdImageAlpha(im, col1) - gdImageAlpha(im, col2);
const int dist = dr * dr + dg * dg + db * db + da * da;
return (100.0 * dist / 195075) < threshold;
}
/*
* To be implemented when we have more image formats.
* Buffer like gray8 gray16 or rgb8 will require some tweak
* and can be done in this function (called from the autocrop
* function. (Pierre)
*/
#if 0
static int colors_equal (const int col1, const in col2)
{
}
#endif

View File

@@ -0,0 +1,14 @@
#ifndef GD_COLOR_H
#define GD_COLOR_H 1
#ifdef __cplusplus
extern "C" {
#endif
int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,794 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gd.h"
#include "gd_color_map.h"
static const gdColorMapEntry GD_COLOR_MAP_X11_ENTRIES[] = {
{"AliceBlue", 240, 248, 255},
{"AntiqueWhite", 250, 235, 215},
{"AntiqueWhite1", 255, 239, 219},
{"AntiqueWhite2", 238, 223, 204},
{"AntiqueWhite3", 205, 192, 176},
{"AntiqueWhite4", 139, 131, 120},
{"BlanchedAlmond", 255, 235, 205},
{"BlueViolet", 138, 43, 226},
{"CadetBlue", 95, 158, 160},
{"CadetBlue1", 152, 245, 255},
{"CadetBlue2", 142, 229, 238},
{"CadetBlue3", 122, 197, 205},
{"CadetBlue4", 83, 134, 139},
{"CornflowerBlue", 100, 149, 237},
{"DarkBlue", 0, 0, 139},
{"DarkCyan", 0, 139, 139},
{"DarkGoldenrod", 184, 134, 11},
{"DarkGoldenrod1", 255, 185, 15},
{"DarkGoldenrod2", 238, 173, 14},
{"DarkGoldenrod3", 205, 149, 12},
{"DarkGoldenrod4", 139, 101, 8},
{"DarkGray", 169, 169, 169},
{"DarkGreen", 0, 100, 0},
{"DarkGrey", 169, 169, 169},
{"DarkKhaki", 189, 183, 107},
{"DarkMagenta", 139, 0, 139},
{"DarkOliveGreen", 85, 107, 47},
{"DarkOliveGreen1", 202, 255, 112},
{"DarkOliveGreen2", 188, 238, 104},
{"DarkOliveGreen3", 162, 205, 90},
{"DarkOliveGreen4", 110, 139, 61},
{"DarkOrange", 255, 140, 0},
{"DarkOrange1", 255, 127, 0},
{"DarkOrange2", 238, 118, 0},
{"DarkOrange3", 205, 102, 0},
{"DarkOrange4", 139, 69, 0},
{"DarkOrchid", 153, 50, 204},
{"DarkOrchid1", 191, 62, 255},
{"DarkOrchid2", 178, 58, 238},
{"DarkOrchid3", 154, 50, 205},
{"DarkOrchid4", 104, 34, 139},
{"DarkRed", 139, 0, 0},
{"DarkSalmon", 233, 150, 122},
{"DarkSeaGreen", 143, 188, 143},
{"DarkSeaGreen1", 193, 255, 193},
{"DarkSeaGreen2", 180, 238, 180},
{"DarkSeaGreen3", 155, 205, 155},
{"DarkSeaGreen4", 105, 139, 105},
{"DarkSlateBlue", 72, 61, 139},
{"DarkSlateGray", 47, 79, 79},
{"DarkSlateGray1", 151, 255, 255},
{"DarkSlateGray2", 141, 238, 238},
{"DarkSlateGray3", 121, 205, 205},
{"DarkSlateGray4", 82, 139, 139},
{"DarkSlateGrey", 47, 79, 79},
{"DarkTurquoise", 0, 206, 209},
{"DarkViolet", 148, 0, 211},
{"DeepPink", 255, 20, 147},
{"DeepPink1", 255, 20, 147},
{"DeepPink2", 238, 18, 137},
{"DeepPink3", 205, 16, 118},
{"DeepPink4", 139, 10, 80},
{"DeepSkyBlue", 0, 191, 255},
{"DeepSkyBlue1", 0, 191, 255},
{"DeepSkyBlue2", 0, 178, 238},
{"DeepSkyBlue3", 0, 154, 205},
{"DeepSkyBlue4", 0, 104, 139},
{"DimGray", 105, 105, 105},
{"DimGrey", 105, 105, 105},
{"DodgerBlue", 30, 144, 255},
{"DodgerBlue1", 30, 144, 255},
{"DodgerBlue2", 28, 134, 238},
{"DodgerBlue3", 24, 116, 205},
{"DodgerBlue4", 16, 78, 139},
{"FloralWhite", 255, 250, 240},
{"ForestGreen", 34, 139, 34},
{"GhostWhite", 248, 248, 255},
{"GreenYellow", 173, 255, 47},
{"HotPink", 255, 105, 180},
{"HotPink1", 255, 110, 180},
{"HotPink2", 238, 106, 167},
{"HotPink3", 205, 96, 144},
{"HotPink4", 139, 58, 98},
{"IndianRed", 205, 92, 92},
{"IndianRed1", 255, 106, 106},
{"IndianRed2", 238, 99, 99},
{"IndianRed3", 205, 85, 85},
{"IndianRed4", 139, 58, 58},
{"LavenderBlush", 255, 240, 245},
{"LavenderBlush1", 255, 240, 245},
{"LavenderBlush2", 238, 224, 229},
{"LavenderBlush3", 205, 193, 197},
{"LavenderBlush4", 139, 131, 134},
{"LawnGreen", 124, 252, 0},
{"LemonChiffon", 255, 250, 205},
{"LemonChiffon1", 255, 250, 205},
{"LemonChiffon2", 238, 233, 191},
{"LemonChiffon3", 205, 201, 165},
{"LemonChiffon4", 139, 137, 112},
{"LightBlue", 173, 216, 230},
{"LightBlue1", 191, 239, 255},
{"LightBlue2", 178, 223, 238},
{"LightBlue3", 154, 192, 205},
{"LightBlue4", 104, 131, 139},
{"LightCoral", 240, 128, 128},
{"LightCyan", 224, 255, 255},
{"LightCyan1", 224, 255, 255},
{"LightCyan2", 209, 238, 238},
{"LightCyan3", 180, 205, 205},
{"LightCyan4", 122, 139, 139},
{"LightGoldenrod", 238, 221, 130},
{"LightGoldenrod1", 255, 236, 139},
{"LightGoldenrod2", 238, 220, 130},
{"LightGoldenrod3", 205, 190, 112},
{"LightGoldenrod4", 139, 129, 76},
{"LightGoldenrodYellow", 250, 250, 210},
{"LightGray", 211, 211, 211},
{"LightGreen", 144, 238, 144},
{"LightGrey", 211, 211, 211},
{"LightPink", 255, 182, 193},
{"LightPink1", 255, 174, 185},
{"LightPink2", 238, 162, 173},
{"LightPink3", 205, 140, 149},
{"LightPink4", 139, 95, 101},
{"LightSalmon", 255, 160, 122},
{"LightSalmon1", 255, 160, 122},
{"LightSalmon2", 238, 149, 114},
{"LightSalmon3", 205, 129, 98},
{"LightSalmon4", 139, 87, 66},
{"LightSeaGreen", 32, 178, 170},
{"LightSkyBlue", 135, 206, 250},
{"LightSkyBlue1", 176, 226, 255},
{"LightSkyBlue2", 164, 211, 238},
{"LightSkyBlue3", 141, 182, 205},
{"LightSkyBlue4", 96, 123, 139},
{"LightSlateBlue", 132, 112, 255},
{"LightSlateGray", 119, 136, 153},
{"LightSlateGrey", 119, 136, 153},
{"LightSteelBlue", 176, 196, 222},
{"LightSteelBlue1", 202, 225, 255},
{"LightSteelBlue2", 188, 210, 238},
{"LightSteelBlue3", 162, 181, 205},
{"LightSteelBlue4", 110, 123, 139},
{"LightYellow", 255, 255, 224},
{"LightYellow1", 255, 255, 224},
{"LightYellow2", 238, 238, 209},
{"LightYellow3", 205, 205, 180},
{"LightYellow4", 139, 139, 122},
{"LimeGreen", 50, 205, 50},
{"MediumAquamarine", 102, 205, 170},
{"MediumBlue", 0, 0, 205},
{"MediumOrchid", 186, 85, 211},
{"MediumOrchid1", 224, 102, 255},
{"MediumOrchid2", 209, 95, 238},
{"MediumOrchid3", 180, 82, 205},
{"MediumOrchid4", 122, 55, 139},
{"MediumPurple", 147, 112, 219},
{"MediumPurple1", 171, 130, 255},
{"MediumPurple2", 159, 121, 238},
{"MediumPurple3", 137, 104, 205},
{"MediumPurple4", 93, 71, 139},
{"MediumSeaGreen", 60, 179, 113},
{"MediumSlateBlue", 123, 104, 238},
{"MediumSpringGreen", 0, 250, 154},
{"MediumTurquoise", 72, 209, 204},
{"MediumVioletRed", 199, 21, 133},
{"MidnightBlue", 25, 25, 112},
{"MintCream", 245, 255, 250},
{"MistyRose", 255, 228, 225},
{"MistyRose1", 255, 228, 225},
{"MistyRose2", 238, 213, 210},
{"MistyRose3", 205, 183, 181},
{"MistyRose4", 139, 125, 123},
{"NavajoWhite", 255, 222, 173},
{"NavajoWhite1", 255, 222, 173},
{"NavajoWhite2", 238, 207, 161},
{"NavajoWhite3", 205, 179, 139},
{"NavajoWhite4", 139, 121, 94},
{"NavyBlue", 0, 0, 128},
{"OldLace", 253, 245, 230},
{"OliveDrab", 107, 142, 35},
{"OliveDrab1", 192, 255, 62},
{"OliveDrab2", 179, 238, 58},
{"OliveDrab3", 154, 205, 50},
{"OliveDrab4", 105, 139, 34},
{"OrangeRed", 255, 69, 0},
{"OrangeRed1", 255, 69, 0},
{"OrangeRed2", 238, 64, 0},
{"OrangeRed3", 205, 55, 0},
{"OrangeRed4", 139, 37, 0},
{"PaleGoldenrod", 238, 232, 170},
{"PaleGreen", 152, 251, 152},
{"PaleGreen1", 154, 255, 154},
{"PaleGreen2", 144, 238, 144},
{"PaleGreen3", 124, 205, 124},
{"PaleGreen4", 84, 139, 84},
{"PaleTurquoise", 175, 238, 238},
{"PaleTurquoise1", 187, 255, 255},
{"PaleTurquoise2", 174, 238, 238},
{"PaleTurquoise3", 150, 205, 205},
{"PaleTurquoise4", 102, 139, 139},
{"PaleVioletRed", 219, 112, 147},
{"PaleVioletRed1", 255, 130, 171},
{"PaleVioletRed2", 238, 121, 159},
{"PaleVioletRed3", 205, 104, 137},
{"PaleVioletRed4", 139, 71, 93},
{"PapayaWhip", 255, 239, 213},
{"PeachPuff", 255, 218, 185},
{"PeachPuff1", 255, 218, 185},
{"PeachPuff2", 238, 203, 173},
{"PeachPuff3", 205, 175, 149},
{"PeachPuff4", 139, 119, 101},
{"PowderBlue", 176, 224, 230},
{"RosyBrown", 188, 143, 143},
{"RosyBrown1", 255, 193, 193},
{"RosyBrown2", 238, 180, 180},
{"RosyBrown3", 205, 155, 155},
{"RosyBrown4", 139, 105, 105},
{"RoyalBlue", 65, 105, 225},
{"RoyalBlue1", 72, 118, 255},
{"RoyalBlue2", 67, 110, 238},
{"RoyalBlue3", 58, 95, 205},
{"RoyalBlue4", 39, 64, 139},
{"SaddleBrown", 139, 69, 19},
{"SandyBrown", 244, 164, 96},
{"SeaGreen", 46, 139, 87},
{"SeaGreen1", 84, 255, 159},
{"SeaGreen2", 78, 238, 148},
{"SeaGreen3", 67, 205, 128},
{"SeaGreen4", 46, 139, 87},
{"SkyBlue", 135, 206, 235},
{"SkyBlue1", 135, 206, 255},
{"SkyBlue2", 126, 192, 238},
{"SkyBlue3", 108, 166, 205},
{"SkyBlue4", 74, 112, 139},
{"SlateBlue", 106, 90, 205},
{"SlateBlue1", 131, 111, 255},
{"SlateBlue2", 122, 103, 238},
{"SlateBlue3", 105, 89, 205},
{"SlateBlue4", 71, 60, 139},
{"SlateGray", 112, 128, 144},
{"SlateGray1", 198, 226, 255},
{"SlateGray2", 185, 211, 238},
{"SlateGray3", 159, 182, 205},
{"SlateGray4", 108, 123, 139},
{"SlateGrey", 112, 128, 144},
{"SpringGreen", 0, 255, 127},
{"SpringGreen1", 0, 255, 127},
{"SpringGreen2", 0, 238, 118},
{"SpringGreen3", 0, 205, 102},
{"SpringGreen4", 0, 139, 69},
{"SteelBlue", 70, 130, 180},
{"SteelBlue1", 99, 184, 255},
{"SteelBlue2", 92, 172, 238},
{"SteelBlue3", 79, 148, 205},
{"SteelBlue4", 54, 100, 139},
{"VioletRed", 208, 32, 144},
{"VioletRed1", 255, 62, 150},
{"VioletRed2", 238, 58, 140},
{"VioletRed3", 205, 50, 120},
{"VioletRed4", 139, 34, 82},
{"WhiteSmoke", 245, 245, 245},
{"YellowGreen", 154, 205, 50},
{"alice blue", 240, 248, 255},
{"antique white", 250, 235, 215},
{"aquamarine", 127, 255, 212},
{"aquamarine1", 127, 255, 212},
{"aquamarine2", 118, 238, 198},
{"aquamarine3", 102, 205, 170},
{"aquamarine4", 69, 139, 116},
{"azure", 240, 255, 255},
{"azure1", 240, 255, 255},
{"azure2", 224, 238, 238},
{"azure3", 193, 205, 205},
{"azure4", 131, 139, 139},
{"beige", 245, 245, 220},
{"bisque", 255, 228, 196},
{"bisque1", 255, 228, 196},
{"bisque2", 238, 213, 183},
{"bisque3", 205, 183, 158},
{"bisque4", 139, 125, 107},
{"black", 0, 0, 0},
{"blanched almond", 255, 235, 205},
{"blue", 0, 0, 255},
{"blue violet", 138, 43, 226},
{"blue1", 0, 0, 255},
{"blue2", 0, 0, 238},
{"blue3", 0, 0, 205},
{"blue4", 0, 0, 139},
{"brown", 165, 42, 42},
{"brown1", 255, 64, 64},
{"brown2", 238, 59, 59},
{"brown3", 205, 51, 51},
{"brown4", 139, 35, 35},
{"burlywood", 222, 184, 135},
{"burlywood1", 255, 211, 155},
{"burlywood2", 238, 197, 145},
{"burlywood3", 205, 170, 125},
{"burlywood4", 139, 115, 85},
{"cadet blue", 95, 158, 160},
{"chartreuse", 127, 255, 0},
{"chartreuse1", 127, 255, 0},
{"chartreuse2", 118, 238, 0},
{"chartreuse3", 102, 205, 0},
{"chartreuse4", 69, 139, 0},
{"chocolate", 210, 105, 30},
{"chocolate1", 255, 127, 36},
{"chocolate2", 238, 118, 33},
{"chocolate3", 205, 102, 29},
{"chocolate4", 139, 69, 19},
{"coral", 255, 127, 80},
{"coral1", 255, 114, 86},
{"coral2", 238, 106, 80},
{"coral3", 205, 91, 69},
{"coral4", 139, 62, 47},
{"cornflower blue", 100, 149, 237},
{"cornsilk", 255, 248, 220},
{"cornsilk1", 255, 248, 220},
{"cornsilk2", 238, 232, 205},
{"cornsilk3", 205, 200, 177},
{"cornsilk4", 139, 136, 120},
{"cyan", 0, 255, 255},
{"cyan1", 0, 255, 255},
{"cyan2", 0, 238, 238},
{"cyan3", 0, 205, 205},
{"cyan4", 0, 139, 139},
{"dark blue", 0, 0, 139},
{"dark cyan", 0, 139, 139},
{"dark goldenrod", 184, 134, 11},
{"dark gray", 169, 169, 169},
{"dark green", 0, 100, 0},
{"dark grey", 169, 169, 169},
{"dark khaki", 189, 183, 107},
{"dark magenta", 139, 0, 139},
{"dark olive green", 85, 107, 47},
{"dark orange", 255, 140, 0},
{"dark orchid", 153, 50, 204},
{"dark red", 139, 0, 0},
{"dark salmon", 233, 150, 122},
{"dark sea green", 143, 188, 143},
{"dark slate blue", 72, 61, 139},
{"dark slate gray", 47, 79, 79},
{"dark slate grey", 47, 79, 79},
{"dark turquoise", 0, 206, 209},
{"dark violet", 148, 0, 211},
{"deep pink", 255, 20, 147},
{"deep sky blue", 0, 191, 255},
{"dim gray", 105, 105, 105},
{"dim grey", 105, 105, 105},
{"dodger blue", 30, 144, 255},
{"firebrick", 178, 34, 34},
{"firebrick1", 255, 48, 48},
{"firebrick2", 238, 44, 44},
{"firebrick3", 205, 38, 38},
{"firebrick4", 139, 26, 26},
{"floral white", 255, 250, 240},
{"forest green", 34, 139, 34},
{"gainsboro", 220, 220, 220},
{"ghost white", 248, 248, 255},
{"gold", 255, 215, 0},
{"gold1", 255, 215, 0},
{"gold2", 238, 201, 0},
{"gold3", 205, 173, 0},
{"gold4", 139, 117, 0},
{"goldenrod", 218, 165, 32},
{"goldenrod1", 255, 193, 37},
{"goldenrod2", 238, 180, 34},
{"goldenrod3", 205, 155, 29},
{"goldenrod4", 139, 105, 20},
{"gray", 190, 190, 190},
{"gray0", 0, 0, 0},
{"gray1", 3, 3, 3},
{"gray10", 26, 26, 26},
{"gray100", 255, 255, 255},
{"gray11", 28, 28, 28},
{"gray12", 31, 31, 31},
{"gray13", 33, 33, 33},
{"gray14", 36, 36, 36},
{"gray15", 38, 38, 38},
{"gray16", 41, 41, 41},
{"gray17", 43, 43, 43},
{"gray18", 46, 46, 46},
{"gray19", 48, 48, 48},
{"gray2", 5, 5, 5},
{"gray20", 51, 51, 51},
{"gray21", 54, 54, 54},
{"gray22", 56, 56, 56},
{"gray23", 59, 59, 59},
{"gray24", 61, 61, 61},
{"gray25", 64, 64, 64},
{"gray26", 66, 66, 66},
{"gray27", 69, 69, 69},
{"gray28", 71, 71, 71},
{"gray29", 74, 74, 74},
{"gray3", 8, 8, 8},
{"gray30", 77, 77, 77},
{"gray31", 79, 79, 79},
{"gray32", 82, 82, 82},
{"gray33", 84, 84, 84},
{"gray34", 87, 87, 87},
{"gray35", 89, 89, 89},
{"gray36", 92, 92, 92},
{"gray37", 94, 94, 94},
{"gray38", 97, 97, 97},
{"gray39", 99, 99, 99},
{"gray4", 10, 10, 10},
{"gray40", 102, 102, 102},
{"gray41", 105, 105, 105},
{"gray42", 107, 107, 107},
{"gray43", 110, 110, 110},
{"gray44", 112, 112, 112},
{"gray45", 115, 115, 115},
{"gray46", 117, 117, 117},
{"gray47", 120, 120, 120},
{"gray48", 122, 122, 122},
{"gray49", 125, 125, 125},
{"gray5", 13, 13, 13},
{"gray50", 127, 127, 127},
{"gray51", 130, 130, 130},
{"gray52", 133, 133, 133},
{"gray53", 135, 135, 135},
{"gray54", 138, 138, 138},
{"gray55", 140, 140, 140},
{"gray56", 143, 143, 143},
{"gray57", 145, 145, 145},
{"gray58", 148, 148, 148},
{"gray59", 150, 150, 150},
{"gray6", 15, 15, 15},
{"gray60", 153, 153, 153},
{"gray61", 156, 156, 156},
{"gray62", 158, 158, 158},
{"gray63", 161, 161, 161},
{"gray64", 163, 163, 163},
{"gray65", 166, 166, 166},
{"gray66", 168, 168, 168},
{"gray67", 171, 171, 171},
{"gray68", 173, 173, 173},
{"gray69", 176, 176, 176},
{"gray7", 18, 18, 18},
{"gray70", 179, 179, 179},
{"gray71", 181, 181, 181},
{"gray72", 184, 184, 184},
{"gray73", 186, 186, 186},
{"gray74", 189, 189, 189},
{"gray75", 191, 191, 191},
{"gray76", 194, 194, 194},
{"gray77", 196, 196, 196},
{"gray78", 199, 199, 199},
{"gray79", 201, 201, 201},
{"gray8", 20, 20, 20},
{"gray80", 204, 204, 204},
{"gray81", 207, 207, 207},
{"gray82", 209, 209, 209},
{"gray83", 212, 212, 212},
{"gray84", 214, 214, 214},
{"gray85", 217, 217, 217},
{"gray86", 219, 219, 219},
{"gray87", 222, 222, 222},
{"gray88", 224, 224, 224},
{"gray89", 227, 227, 227},
{"gray9", 23, 23, 23},
{"gray90", 229, 229, 229},
{"gray91", 232, 232, 232},
{"gray92", 235, 235, 235},
{"gray93", 237, 237, 237},
{"gray94", 240, 240, 240},
{"gray95", 242, 242, 242},
{"gray96", 245, 245, 245},
{"gray97", 247, 247, 247},
{"gray98", 250, 250, 250},
{"gray99", 252, 252, 252},
{"green", 0, 255, 0},
{"green yellow", 173, 255, 47},
{"green1", 0, 255, 0},
{"green2", 0, 238, 0},
{"green3", 0, 205, 0},
{"green4", 0, 139, 0},
{"grey", 190, 190, 190},
{"grey0", 0, 0, 0},
{"grey1", 3, 3, 3},
{"grey10", 26, 26, 26},
{"grey100", 255, 255, 255},
{"grey11", 28, 28, 28},
{"grey12", 31, 31, 31},
{"grey13", 33, 33, 33},
{"grey14", 36, 36, 36},
{"grey15", 38, 38, 38},
{"grey16", 41, 41, 41},
{"grey17", 43, 43, 43},
{"grey18", 46, 46, 46},
{"grey19", 48, 48, 48},
{"grey2", 5, 5, 5},
{"grey20", 51, 51, 51},
{"grey21", 54, 54, 54},
{"grey22", 56, 56, 56},
{"grey23", 59, 59, 59},
{"grey24", 61, 61, 61},
{"grey25", 64, 64, 64},
{"grey26", 66, 66, 66},
{"grey27", 69, 69, 69},
{"grey28", 71, 71, 71},
{"grey29", 74, 74, 74},
{"grey3", 8, 8, 8},
{"grey30", 77, 77, 77},
{"grey31", 79, 79, 79},
{"grey32", 82, 82, 82},
{"grey33", 84, 84, 84},
{"grey34", 87, 87, 87},
{"grey35", 89, 89, 89},
{"grey36", 92, 92, 92},
{"grey37", 94, 94, 94},
{"grey38", 97, 97, 97},
{"grey39", 99, 99, 99},
{"grey4", 10, 10, 10},
{"grey40", 102, 102, 102},
{"grey41", 105, 105, 105},
{"grey42", 107, 107, 107},
{"grey43", 110, 110, 110},
{"grey44", 112, 112, 112},
{"grey45", 115, 115, 115},
{"grey46", 117, 117, 117},
{"grey47", 120, 120, 120},
{"grey48", 122, 122, 122},
{"grey49", 125, 125, 125},
{"grey5", 13, 13, 13},
{"grey50", 127, 127, 127},
{"grey51", 130, 130, 130},
{"grey52", 133, 133, 133},
{"grey53", 135, 135, 135},
{"grey54", 138, 138, 138},
{"grey55", 140, 140, 140},
{"grey56", 143, 143, 143},
{"grey57", 145, 145, 145},
{"grey58", 148, 148, 148},
{"grey59", 150, 150, 150},
{"grey6", 15, 15, 15},
{"grey60", 153, 153, 153},
{"grey61", 156, 156, 156},
{"grey62", 158, 158, 158},
{"grey63", 161, 161, 161},
{"grey64", 163, 163, 163},
{"grey65", 166, 166, 166},
{"grey66", 168, 168, 168},
{"grey67", 171, 171, 171},
{"grey68", 173, 173, 173},
{"grey69", 176, 176, 176},
{"grey7", 18, 18, 18},
{"grey70", 179, 179, 179},
{"grey71", 181, 181, 181},
{"grey72", 184, 184, 184},
{"grey73", 186, 186, 186},
{"grey74", 189, 189, 189},
{"grey75", 191, 191, 191},
{"grey76", 194, 194, 194},
{"grey77", 196, 196, 196},
{"grey78", 199, 199, 199},
{"grey79", 201, 201, 201},
{"grey8", 20, 20, 20},
{"grey80", 204, 204, 204},
{"grey81", 207, 207, 207},
{"grey82", 209, 209, 209},
{"grey83", 212, 212, 212},
{"grey84", 214, 214, 214},
{"grey85", 217, 217, 217},
{"grey86", 219, 219, 219},
{"grey87", 222, 222, 222},
{"grey88", 224, 224, 224},
{"grey89", 227, 227, 227},
{"grey9", 23, 23, 23},
{"grey90", 229, 229, 229},
{"grey91", 232, 232, 232},
{"grey92", 235, 235, 235},
{"grey93", 237, 237, 237},
{"grey94", 240, 240, 240},
{"grey95", 242, 242, 242},
{"grey96", 245, 245, 245},
{"grey97", 247, 247, 247},
{"grey98", 250, 250, 250},
{"grey99", 252, 252, 252},
{"honeydew", 240, 255, 240},
{"honeydew1", 240, 255, 240},
{"honeydew2", 224, 238, 224},
{"honeydew3", 193, 205, 193},
{"honeydew4", 131, 139, 131},
{"hot pink", 255, 105, 180},
{"indian red", 205, 92, 92},
{"ivory", 255, 255, 240},
{"ivory1", 255, 255, 240},
{"ivory2", 238, 238, 224},
{"ivory3", 205, 205, 193},
{"ivory4", 139, 139, 131},
{"khaki", 240, 230, 140},
{"khaki1", 255, 246, 143},
{"khaki2", 238, 230, 133},
{"khaki3", 205, 198, 115},
{"khaki4", 139, 134, 78},
{"lavender", 230, 230, 250},
{"lavender blush", 255, 240, 245},
{"lawn green", 124, 252, 0},
{"lemon chiffon", 255, 250, 205},
{"light blue", 173, 216, 230},
{"light coral", 240, 128, 128},
{"light cyan", 224, 255, 255},
{"light goldenrod", 238, 221, 130},
{"light goldenrod yellow", 250, 250, 210},
{"light gray", 211, 211, 211},
{"light green", 144, 238, 144},
{"light grey", 211, 211, 211},
{"light pink", 255, 182, 193},
{"light salmon", 255, 160, 122},
{"light sea green", 32, 178, 170},
{"light sky blue", 135, 206, 250},
{"light slate blue", 132, 112, 255},
{"light slate gray", 119, 136, 153},
{"light slate grey", 119, 136, 153},
{"light steel blue", 176, 196, 222},
{"light yellow", 255, 255, 224},
{"lime green", 50, 205, 50},
{"linen", 250, 240, 230},
{"magenta", 255, 0, 255},
{"magenta1", 255, 0, 255},
{"magenta2", 238, 0, 238},
{"magenta3", 205, 0, 205},
{"magenta4", 139, 0, 139},
{"maroon", 176, 48, 96},
{"maroon1", 255, 52, 179},
{"maroon2", 238, 48, 167},
{"maroon3", 205, 41, 144},
{"maroon4", 139, 28, 98},
{"medium aquamarine", 102, 205, 170},
{"medium blue", 0, 0, 205},
{"medium orchid", 186, 85, 211},
{"medium purple", 147, 112, 219},
{"medium sea green", 60, 179, 113},
{"medium slate blue", 123, 104, 238},
{"medium spring green", 0, 250, 154},
{"medium turquoise", 72, 209, 204},
{"medium violet red", 199, 21, 133},
{"midnight blue", 25, 25, 112},
{"mint cream", 245, 255, 250},
{"misty rose", 255, 228, 225},
{"moccasin", 255, 228, 181},
{"navajo white", 255, 222, 173},
{"navy", 0, 0, 128},
{"navy blue", 0, 0, 128},
{"old lace", 253, 245, 230},
{"olive drab", 107, 142, 35},
{"orange", 255, 165, 0},
{"orange red", 255, 69, 0},
{"orange1", 255, 165, 0},
{"orange2", 238, 154, 0},
{"orange3", 205, 133, 0},
{"orange4", 139, 90, 0},
{"orchid", 218, 112, 214},
{"orchid1", 255, 131, 250},
{"orchid2", 238, 122, 233},
{"orchid3", 205, 105, 201},
{"orchid4", 139, 71, 137},
{"pale goldenrod", 238, 232, 170},
{"pale green", 152, 251, 152},
{"pale turquoise", 175, 238, 238},
{"pale violet red", 219, 112, 147},
{"papaya whip", 255, 239, 213},
{"peach puff", 255, 218, 185},
{"peru", 205, 133, 63},
{"pink", 255, 192, 203},
{"pink1", 255, 181, 197},
{"pink2", 238, 169, 184},
{"pink3", 205, 145, 158},
{"pink4", 139, 99, 108},
{"plum", 221, 160, 221},
{"plum1", 255, 187, 255},
{"plum2", 238, 174, 238},
{"plum3", 205, 150, 205},
{"plum4", 139, 102, 139},
{"powder blue", 176, 224, 230},
{"purple", 160, 32, 240},
{"purple1", 155, 48, 255},
{"purple2", 145, 44, 238},
{"purple3", 125, 38, 205},
{"purple4", 85, 26, 139},
{"red", 255, 0, 0},
{"red1", 255, 0, 0},
{"red2", 238, 0, 0},
{"red3", 205, 0, 0},
{"red4", 139, 0, 0},
{"rosy brown", 188, 143, 143},
{"royal blue", 65, 105, 225},
{"saddle brown", 139, 69, 19},
{"salmon", 250, 128, 114},
{"salmon1", 255, 140, 105},
{"salmon2", 238, 130, 98},
{"salmon3", 205, 112, 84},
{"salmon4", 139, 76, 57},
{"sandy brown", 244, 164, 96},
{"sea green", 46, 139, 87},
{"seashell", 255, 245, 238},
{"seashell1", 255, 245, 238},
{"seashell2", 238, 229, 222},
{"seashell3", 205, 197, 191},
{"seashell4", 139, 134, 130},
{"sienna", 160, 82, 45},
{"sienna1", 255, 130, 71},
{"sienna2", 238, 121, 66},
{"sienna3", 205, 104, 57},
{"sienna4", 139, 71, 38},
{"sky blue", 135, 206, 235},
{"slate blue", 106, 90, 205},
{"slate gray", 112, 128, 144},
{"slate grey", 112, 128, 144},
{"snow", 255, 250, 250},
{"snow1", 255, 250, 250},
{"snow2", 238, 233, 233},
{"snow3", 205, 201, 201},
{"snow4", 139, 137, 137},
{"spring green", 0, 255, 127},
{"steel blue", 70, 130, 180},
{"tan", 210, 180, 140},
{"tan1", 255, 165, 79},
{"tan2", 238, 154, 73},
{"tan3", 205, 133, 63},
{"tan4", 139, 90, 43},
{"thistle", 216, 191, 216},
{"thistle1", 255, 225, 255},
{"thistle2", 238, 210, 238},
{"thistle3", 205, 181, 205},
{"thistle4", 139, 123, 139},
{"tomato", 255, 99, 71},
{"tomato1", 255, 99, 71},
{"tomato2", 238, 92, 66},
{"tomato3", 205, 79, 57},
{"tomato4", 139, 54, 38},
{"turquoise", 64, 224, 208},
{"turquoise1", 0, 245, 255},
{"turquoise2", 0, 229, 238},
{"turquoise3", 0, 197, 205},
{"turquoise4", 0, 134, 139},
{"violet", 238, 130, 238},
{"violet red", 208, 32, 144},
{"wheat", 245, 222, 179},
{"wheat1", 255, 231, 186},
{"wheat2", 238, 216, 174},
{"wheat3", 205, 186, 150},
{"wheat4", 139, 126, 102},
{"white", 255, 255, 255},
{"white smoke", 245, 245, 245},
{"yellow", 255, 255, 0},
{"yellow green", 154, 205, 50},
{"yellow1", 255, 255, 0},
{"yellow2", 238, 238, 0},
{"yellow3", 205, 205, 0},
{"yellow4", 139, 139, 0},
};
BGD_EXPORT_DATA_PROT gdColorMap GD_COLOR_MAP_X11 = {
sizeof(GD_COLOR_MAP_X11_ENTRIES)/sizeof(gdColorMapEntry),
(gdColorMapEntry *)GD_COLOR_MAP_X11_ENTRIES
};
/*
Function: gdColorMapLookup
*/
BGD_DECLARE(int)
gdColorMapLookup(const gdColorMap color_map, const char *color_name, int *r, int *g, int *b)
{
gdColorMapEntry *entries = color_map.entries;
int low = 0;
int high = color_map.num_entries - 1;
while (low <= high) {
int i = (low+high)/2;
int result = strcmp(color_name, entries[i].color_name);
if (result == 0) {
*r = entries[i].red;
*g = entries[i].green;
*b = entries[i].blue;
return 1;
} else if (result < 0) {
high = i - 1;
} else {
low = i + 1;
}
}
return 0;
}

View File

@@ -0,0 +1,63 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "gd.h"
#include "gdhelpers.h"
/*
Function: gdImageColorMatch
Bring the palette colors in im2 to be closer to im1.
*/
BGD_DECLARE(int) gdImageColorMatch (gdImagePtr im1, gdImagePtr im2)
{
unsigned long *buf; /* stores our calculations */
unsigned long *bp; /* buf ptr */
int color, rgb;
int x,y;
int count;
if (!im1->trueColor) {
return -1; /* im1 must be True Color */
}
if (im2->trueColor) {
return -2; /* im2 must be indexed */
}
if ((im1->sx != im2->sx) || (im1->sy != im2->sy)) {
return -3; /* the images are meant to be the same dimensions */
}
if (im2->colorsTotal < 1) {
return -4; /* At least 1 color must be allocated */
}
buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * im2->colorsTotal);
memset (buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal );
for (x=0; x < im1->sx; x++) {
for( y=0; y<im1->sy; y++ ) {
color = im2->pixels[y][x];
rgb = im1->tpixels[y][x];
bp = buf + (color * 5);
(*(bp++))++;
*(bp++) += gdTrueColorGetRed(rgb);
*(bp++) += gdTrueColorGetGreen(rgb);
*(bp++) += gdTrueColorGetBlue(rgb);
*(bp++) += gdTrueColorGetAlpha(rgb);
}
}
bp = buf;
for (color=0; color < im2->colorsTotal; color++) {
count = *(bp++);
if( count > 0 ) {
im2->red[color] = *(bp++) / count;
im2->green[color] = *(bp++) / count;
im2->blue[color] = *(bp++) / count;
im2->alpha[color] = *(bp++) / count;
} else {
bp += 4;
}
}
gdFree(buf);
return 0;
}

View File

@@ -0,0 +1,309 @@
/**
* File: Cropping
*
* Crop an image
*
* Some functions to crop images, automatically (auto detection of the border
* color), using a given color (with or without tolerance) or using a given
* rectangle.
*
* Example:
* (start code)
* im2 = gdImageAutoCrop(im, GD_CROP_SIDES);
* if (im2) {
* gdImageDestroy(im); // unless you need the original image subsequently
* // do something with the cropped image
* }
* gdImageDestroy(im2);
* (end code)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include "gd.h"
#include "gd_color.h"
static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color);
/**
* Function: gdImageCrop
*
* Crop an image to a given rectangle
*
* Parameters:
* src - The image.
* crop - The cropping rectangle, see <gdRect>.
*
* Returns:
* The newly created cropped image, or NULL on failure.
*
* See also:
* - <gdImageCropAuto>
* - <gdImageCropThreshold>
*/
BGD_DECLARE(gdImagePtr) gdImageCrop(gdImagePtr src, const gdRect *crop)
{
gdImagePtr dst;
if (gdImageTrueColor(src)) {
dst = gdImageCreateTrueColor(crop->width, crop->height);
} else {
dst = gdImageCreate(crop->width, crop->height);
}
if (!dst) return NULL;
gdImageCopy(dst, src, 0, 0, crop->x, crop->y, crop->width, crop->height);
return dst;
}
/**
* Function: gdImageCropAuto
*
* Crop an image automatically
*
* This function detects the cropping area according to the given _mode_.
*
* Parameters:
* im - The image.
* mode - The cropping mode, see <gdCropMode>.
*
* Returns:
* The newly created cropped image, or NULL on failure.
*
* See also:
* - <gdImageCrop>
* - <gdImageCropThreshold>
*/
BGD_DECLARE(gdImagePtr) gdImageCropAuto(gdImagePtr im, const unsigned int mode)
{
const int width = gdImageSX(im);
const int height = gdImageSY(im);
int x,y;
int color, match;
gdRect crop;
crop.x = 0;
crop.y = 0;
crop.width = 0;
crop.height = 0;
switch (mode) {
case GD_CROP_TRANSPARENT:
color = gdImageGetTransparent(im);
break;
case GD_CROP_BLACK:
color = gdImageColorClosestAlpha(im, 0, 0, 0, 0);
break;
case GD_CROP_WHITE:
color = gdImageColorClosestAlpha(im, 255, 255, 255, 0);
break;
case GD_CROP_SIDES:
gdGuessBackgroundColorFromCorners(im, &color);
break;
case GD_CROP_DEFAULT:
default:
color = gdImageGetTransparent(im);
break;
}
/* TODO: Add gdImageGetRowPtr and works with ptr at the row level
* for the true color and palette images
* new formats will simply work with ptr
*/
match = 1;
for (y = 0; match && y < height; y++) {
for (x = 0; match && x < width; x++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
/* Nothing to do > bye
* Duplicate the image?
*/
if (y == height - 1) {
return NULL;
}
crop.y = y -1;
match = 1;
for (y = height - 1; match && y >= 0; y--) {
for (x = 0; match && x < width; x++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
if (y == 0) {
crop.height = height - crop.y + 1;
} else {
crop.height = y - crop.y + 2;
}
match = 1;
for (x = 0; match && x < width; x++) {
for (y = 0; match && y < crop.y + crop.height - 1; y++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
crop.x = x - 1;
match = 1;
for (x = width - 1; match && x >= 0; x--) {
for (y = 0; match && y < crop.y + crop.height - 1; y++) {
match = (color == gdImageGetPixel(im, x,y));
}
}
crop.width = x - crop.x + 2;
return gdImageCrop(im, &crop);
}
/**
* Function: gdImageCropThreshold
*
* Crop an image using a given color
*
* The _threshold_ defines the tolerance to be used while comparing the image
* color and the color to crop. The method used to calculate the color
* difference is based on the color distance in the RGB(A) cube.
*
* Parameters:
* im - The image.
* color - The crop color.
* threshold - The crop threshold.
*
* Returns:
* The newly created cropped image, or NULL on failure.
*
* See also:
* - <gdImageCrop>
* - <gdImageCropAuto>
*/
BGD_DECLARE(gdImagePtr) gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold)
{
const int width = gdImageSX(im);
const int height = gdImageSY(im);
int x,y;
int match;
gdRect crop;
crop.x = 0;
crop.y = 0;
crop.width = 0;
crop.height = 0;
/* Pierre: crop everything sounds bad */
if (threshold > 100.0) {
return NULL;
}
if (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im)) {
return NULL;
}
/* TODO: Add gdImageGetRowPtr and works with ptr at the row level
* for the true color and palette images
* new formats will simply work with ptr
*/
match = 1;
for (y = 0; match && y < height; y++) {
for (x = 0; match && x < width; x++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
}
}
/* Pierre
* Nothing to do > bye
* Duplicate the image?
*/
if (y == height - 1) {
return NULL;
}
crop.y = y -1;
match = 1;
for (y = height - 1; match && y >= 0; y--) {
for (x = 0; match && x < width; x++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0;
}
}
if (y == 0) {
crop.height = height - crop.y + 1;
} else {
crop.height = y - crop.y + 2;
}
match = 1;
for (x = 0; match && x < width; x++) {
for (y = 0; match && y < crop.y + crop.height - 1; y++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
}
}
crop.x = x - 1;
match = 1;
for (x = width - 1; match && x >= 0; x--) {
for (y = 0; match && y < crop.y + crop.height - 1; y++) {
match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
}
}
crop.width = x - crop.x + 2;
return gdImageCrop(im, &crop);
}
/* This algorithm comes from pnmcrop (http://netpbm.sourceforge.net/)
* Three steps:
* - if 3 corners are equal.
* - if two are equal.
* - Last solution: average the colors
*/
static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color)
{
const int tl = gdImageGetPixel(im, 0, 0);
const int tr = gdImageGetPixel(im, gdImageSX(im) - 1, 0);
const int bl = gdImageGetPixel(im, 0, gdImageSY(im) -1);
const int br = gdImageGetPixel(im, gdImageSX(im) - 1, gdImageSY(im) -1);
if (tr == bl && tr == br) {
*color = tr;
return 3;
} else if (tl == bl && tl == br) {
*color = tl;
return 3;
} else if (tl == tr && tl == br) {
*color = tl;
return 3;
} else if (tl == tr && tl == bl) {
*color = tl;
return 3;
} else if (tl == tr || tl == bl || tl == br) {
*color = tl;
return 2;
} else if (tr == bl) {
*color = tr;
return 2;
} else if (br == bl) {
*color = bl;
return 2;
} else {
register int r,b,g,a;
r = (int)(0.5f + (gdImageRed(im, tl) + gdImageRed(im, tr) + gdImageRed(im, bl) + gdImageRed(im, br)) / 4);
g = (int)(0.5f + (gdImageGreen(im, tl) + gdImageGreen(im, tr) + gdImageGreen(im, bl) + gdImageGreen(im, br)) / 4);
b = (int)(0.5f + (gdImageBlue(im, tl) + gdImageBlue(im, tr) + gdImageBlue(im, bl) + gdImageBlue(im, br)) / 4);
a = (int)(0.5f + (gdImageAlpha(im, tl) + gdImageAlpha(im, tr) + gdImageAlpha(im, bl) + gdImageAlpha(im, br)) / 4);
*color = gdImageColorClosestAlpha(im, r, g, b, a);
return 0;
}
}

View File

@@ -0,0 +1,254 @@
/* Convenience functions to read or write images from or to disk,
* determining file type from the filename extension. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include "gd.h"
typedef gdImagePtr (BGD_STDCALL *ReadFn)(FILE *in);
typedef void (BGD_STDCALL *WriteFn)(gdImagePtr im, FILE *out);
typedef gdImagePtr (BGD_STDCALL *LoadFn)(char *filename);
#ifdef HAVE_LIBZ
static void BGD_STDCALL writegd2(gdImagePtr im, FILE *out) {
gdImageGd2(im, out, 0, GD2_FMT_COMPRESSED);
}/* writegd*/
#endif
#ifdef HAVE_LIBJPEG
static void BGD_STDCALL writejpeg(gdImagePtr im, FILE *out) {
gdImageJpeg(im, out, -1);
}/* writejpeg*/
#endif
static void BGD_STDCALL writewbmp(gdImagePtr im, FILE *out) {
int fg = gdImageColorClosest(im, 0, 0, 0);
gdImageWBMP(im, fg, out);
}/* writejpeg*/
static void BGD_STDCALL writebmp(gdImagePtr im, FILE *out) {
gdImageBmp(im, out, GD_TRUE);
}/* writejpeg*/
enum FType {UNKNOWN, PNG, JPG, GIF, TIFF, GD, GD2, WEBP};
static struct FileType {
const char *ext;
ReadFn reader;
WriteFn writer;
LoadFn loader;
} Types[] = {
{".gif", gdImageCreateFromGif, gdImageGif, NULL},
{".gd", gdImageCreateFromGd, gdImageGd, NULL},
{".wbmp", gdImageCreateFromWBMP, writewbmp, NULL},
{".bmp", gdImageCreateFromBmp, writebmp, NULL},
{".xbm", gdImageCreateFromXbm, NULL, NULL},
{".tga", gdImageCreateFromTga, NULL, NULL},
#ifdef HAVE_LIBPNG
{".png", gdImageCreateFromPng, gdImagePng, NULL},
#endif
#ifdef HAVE_LIBJPEG
{".jpg", gdImageCreateFromJpeg, writejpeg, NULL},
{".jpeg", gdImageCreateFromJpeg, writejpeg, NULL},
#endif
#ifdef HAVE_LIBTIFF
{".tiff", gdImageCreateFromTiff, gdImageTiff, NULL},
{".tif" , gdImageCreateFromTiff, gdImageTiff, NULL},
#endif
#ifdef HAVE_LIBZ
{".gd2", gdImageCreateFromGd2, writegd2, NULL},
#endif
#ifdef HAVE_LIBWEBP
{".webp", gdImageCreateFromWebp, gdImageWebp, NULL},
#endif
#ifdef HAVE_LIBXPM
{".xpm", NULL, NULL, gdImageCreateFromXpm},
#endif
{NULL, NULL, NULL}
};
struct FileType *
ftype(const char *filename) {
int n;
char *ext;
/* Find the file extension (i.e. the last period in the string. */
ext = strrchr(filename, '.');
if (!ext) return NULL;
for (n = 0; Types[n].ext; n++) {
if (strcasecmp(ext, Types[n].ext) == 0) {
return &Types[n];
}/* if */
}/* for */
return NULL;
}/* ftype*/
/*
Function: gdSupportsFileType
Tests if a given file type is supported by GD.
Given the name of an image file (which does not have to exist),
returns 1 (i.e. TRUE) if <gdImageCreateFromFile> can read a file
of that type. This is useful if you do not know which image types
were enabled at compile time.
If _writing_ is true, the result will be true only if
<gdImageFile> can write a file of this type.
Note that filename parsing is done exactly the same as is done by
<gdImageCreateFromFile> and <gdImageFile> and is subject to the
same limitations.
Assuming LibGD is compiled with support for these image types, the
following extensions are supported:
- .gif
- .gd, .gd2
- .wbmp
- .bmp
- .xbm
- .tga
- .png
- .jpg, .jpeg
- .tiff, .tif
- .webp
- .xpm
Names are parsed case-insenstively.
Parameters:
filename - Filename with tested extension.
writing - Flag: true tests if writing works
Returns:
GD_TRUE (1) if the file type is supported, GD_FALSE (0) if not.
*/
BGD_DECLARE(int)
gdSupportsFileType(const char *filename, int writing) {
struct FileType *entry = ftype(filename);
return !!entry && (!writing || !!entry->writer);
}/* gdSupportsFileType*/
/*
Function: gdImageCreateFromFile
Read an image file of any supported.
Given the path to a file, <gdImageCreateFromFile> will open the
file, read its contents with the appropriate _gdImageCreateFrom*_
function and return it.
File type is determined by the filename extension, so having an
incorrect extension will probably not work. For example, renaming
PNG image "foo.png" to "foo.gif" and then attempting to load it
will fail even if GD supports both formats. See
<gdSupportsFiletype> for more details.
NULL is returned on error.
Parameters:
filename - the input file name
Returns:
A pointer to the new image or NULL if an error occurred.
*/
BGD_DECLARE(gdImagePtr)
gdImageCreateFromFile(const char *filename) {
struct FileType *entry = ftype(filename);
FILE *fh;
gdImagePtr result;
if (!entry) return NULL;
if (entry->loader) return entry->loader((char *)filename);
if (!entry->reader) return NULL;
fh = fopen(filename, "rb");
if (!fh) return NULL;
result = entry->reader(fh);
fclose(fh);
return result;
}/* gdImageCreateFromFile*/
/*
Function: gdImageFile
Writes an image to a file in the format indicated by the filename.
File type is determined by the extension of the file name. See
<gdSupportsFiletype> for an overview of the parsing.
For file types that require extra arguments, <gdImageFile>
attempts to use sane defaults:
<gdImageGd2> - chunk size = 0, compression is enabled.
<gdImageJpeg> - quality = -1 (i.e. the reasonable default)
<gdImageWBMP> - foreground is the darkest available color
Everything else is called with the two-argument function and so
will use the default values.
<gdImageFile> has some rudimentary error detection and will return
GD_FALSE (0) if a detectable error occurred. However, the image
loaders do not normally return their error status so a result of
GD_TRUE (1) does **not** mean the file was saved successfully.
Parameters:
im - The image to save.
filename - The path to the file to which the image is saved.
Returns:
GD_FALSE (0) if an error was detected, GD_TRUE (1) if not.
*/
BGD_DECLARE(int)
gdImageFile(gdImagePtr im, const char *filename) {
struct FileType *entry = ftype(filename);
FILE *fh;
if (!entry || !entry->writer) return GD_FALSE;
fh = fopen(filename, "wb");
if (!fh) return GD_FALSE;
entry->writer(im, fh);
fclose(fh);
return GD_TRUE;
}/* gdImageFile*/

File diff suppressed because it is too large Load Diff

389
project/jni/gd/src/gd_gd.c Normal file
View File

@@ -0,0 +1,389 @@
/**
* File: GD IO
*
* Read and write GD images.
*
* The GD image format is a proprietary image format of libgd. *It has to be*
* *regarded as being obsolete, and should only be used for development and*
* *testing purposes.*
*
* Structure of a GD image file:
* - file header
* - color header (either truecolor or palette)
* - image data
*
* All numbers are stored in big-endian format.
*
* File header structure:
* signature - 1 word ("\xFF\xFE" for truecolor, "\xFF\xFF" for palette)
* width - 1 word
* height - 1 word
*
* Truecolor image color header:
* truecolor - 1 byte (always "\001")
* transparent - 1 dword (ARGB color)
*
* Palette image color header:
* truecolor - 1 byte (always "\0")
* count - 1 word (the number of used palette colors)
* transparent - 1 dword (ARGB color)
* palette - 256 dwords (RGBA colors)
*
* Image data:
* Sequential pixel data; row-major from top to bottom, left to right:
* - 1 byte per pixel for palette images
* - 1 dword (ARGB) per pixel for truecolor images
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#define TRUE 1
#define FALSE 0
/* Use this for commenting out debug-print statements. */
/* Just use the first '#define' to allow all the prints... */
/*#define GD2_DBG(s) (s) */
#define GD2_DBG(s)
/* */
/* Shared code to read color tables from gd file. */
/* */
int
_gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
{
int i;
if (gd2xFlag) {
int trueColorFlag;
if (!gdGetByte (&trueColorFlag, in)) {
goto fail1;
}
/* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12.
Beginning in 2.0.12 truecolor is indicated by the initial 2-byte
signature. */
if (trueColorFlag != im->trueColor) {
goto fail1;
}
/* This should have been a word all along */
if (!im->trueColor) {
if (!gdGetWord (&im->colorsTotal, in)) {
goto fail1;
}
if (im->colorsTotal > gdMaxColors) {
goto fail1;
}
}
/* Int to accommodate truecolor single-color transparency */
if (!gdGetInt (&im->transparent, in)) {
goto fail1;
}
} else {
if (!gdGetByte (&im->colorsTotal, in)) {
goto fail1;
}
if (!gdGetWord (&im->transparent, in)) {
goto fail1;
}
if (im->transparent == 257) {
im->transparent = (-1);
}
}
GD2_DBG (printf
("Palette had %d colours (T=%d)\n", im->colorsTotal,
im->transparent));
if (im->trueColor) {
return TRUE;
}
for (i = 0; (i < gdMaxColors); i++) {
if (!gdGetByte (&im->red[i], in)) {
goto fail1;
}
if (!gdGetByte (&im->green[i], in)) {
goto fail1;
}
if (!gdGetByte (&im->blue[i], in)) {
goto fail1;
}
if (gd2xFlag) {
if (!gdGetByte (&im->alpha[i], in)) {
goto fail1;
}
}
}
for (i = 0; (i < im->colorsTotal); i++) {
im->open[i] = 0;
};
return TRUE;
fail1:
return FALSE;
}
/* */
/* Use the common basic header info to make the image object. */
/* */
static gdImagePtr
_gdCreateFromFile (gdIOCtx * in, int *sx, int *sy)
{
gdImagePtr im;
int gd2xFlag = 0;
int trueColorFlag = 0;
if (!gdGetWord (sx, in)) {
goto fail1;
}
if ((*sx == 65535) || (*sx == 65534)) {
/* This is a gd 2.0 .gd file */
gd2xFlag = 1;
/* 2.0.12: 65534 signals a truecolor .gd file.
There is a slight redundancy here but we can
live with it. */
if (*sx == 65534) {
trueColorFlag = 1;
}
if (!gdGetWord (sx, in)) {
goto fail1;
}
}
if (!gdGetWord (sy, in)) {
goto fail1;
}
GD2_DBG (printf ("Image is %dx%d\n", *sx, *sy));
if (trueColorFlag) {
im = gdImageCreateTrueColor (*sx, *sy);
} else {
im = gdImageCreate (*sx, *sy);
}
if (!im) {
goto fail1;
}
if (!_gdGetColors (in, im, gd2xFlag)) {
goto fail2;
}
return im;
fail2:
gdImageDestroy (im);
fail1:
return 0;
}
/*
Function: gdImageCreateFromGd
<gdImageCreateFromGd> is called to load images from gd format
files. Invoke <gdImageCreateFromGd> with an already opened pointer
to a file containing the desired image in the gd file format,
which is specific to gd and intended for very fast loading. (It is
not intended for compression; for compression, use PNG or JPEG.)
<gdImageCreateFromGd> returns a <gdImagePtr> to the new image, or
NULL if unable to load the image (most often because the file is
corrupt or does not contain a gd format
image). <gdImageCreateFromGd> does not close the file. You can
inspect the sx and sy members of the image to determine its
size. The image must eventually be destroyed using
<gdImageDestroy>.
Variants:
<gdImageCreateFromGdPtr> creates an image from GD data (i.e. the
contents of a GD file) already in memory.
<gdImageCreateFromGdCtx> reads in an image using the functions in
a <gdIOCtx> struct.
Parameters:
infile - The input FILE pointer
Returns:
A pointer to the new image or NULL if an error occurred.
Example:
> gdImagePtr im;
> FILE *in;
> in = fopen("mygd.gd", "rb");
> im = gdImageCreateFromGd(in);
> fclose(in);
> // ... Use the image ...
> gdImageDestroy(im);
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromGd (FILE * inFile)
{
gdImagePtr im;
gdIOCtx *in;
in = gdNewFileCtx (inFile);
if (in == NULL) return NULL;
im = gdImageCreateFromGdCtx (in);
in->gd_free (in);
return im;
}
/*
Function: gdImageCreateFromGdPtr
Parameters:
size - size of GD data in bytes.
data - GD data (i.e. contents of a GIF file).
Reads in GD data from memory. See <gdImageCreateFromGd>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromGdPtr (int size, void *data)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0);
if(!in)
return 0;
im = gdImageCreateFromGdCtx (in);
in->gd_free (in);
return im;
}
/*
Function: gdImageCreateFromGdCtx
Reads in a GD image via a <gdIOCtx> struct. See
<gdImageCreateFromGd>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromGdCtx (gdIOCtxPtr in)
{
int sx, sy;
int x, y;
gdImagePtr im;
/* Read the header */
im = _gdCreateFromFile (in, &sx, &sy);
if (im == NULL) {
goto fail1;
};
/* Then the data... */
/* 2.0.12: support truecolor properly in .gd as well as in .gd2.
Problem reported by Andreas Pfaller. */
if (im->trueColor) {
for (y = 0; (y < sy); y++) {
for (x = 0; (x < sx); x++) {
int pix;
if (!gdGetInt (&pix, in)) {
goto fail2;
}
im->tpixels[y][x] = pix;
}
}
} else {
for (y = 0; (y < sy); y++) {
for (x = 0; (x < sx); x++) {
int ch;
ch = gdGetC (in);
if (ch == EOF) {
goto fail2;
}
/* ROW-MAJOR IN GD 1.3 */
im->pixels[y][x] = ch;
}
}
}
return im;
fail2:
gdImageDestroy (im);
fail1:
return 0;
}
void
_gdPutColors (gdImagePtr im, gdIOCtx * out)
{
int i;
gdPutC (im->trueColor, out);
if (!im->trueColor) {
gdPutWord (im->colorsTotal, out);
}
gdPutInt (im->transparent, out);
if (!im->trueColor) {
for (i = 0; (i < gdMaxColors); i++) {
gdPutC ((unsigned char) im->red[i], out);
gdPutC ((unsigned char) im->green[i], out);
gdPutC ((unsigned char) im->blue[i], out);
gdPutC ((unsigned char) im->alpha[i], out);
}
}
}
static void
_gdPutHeader (gdImagePtr im, gdIOCtx * out)
{
/* 65535 indicates this is a gd 2.x .gd file.
2.0.12: 65534 indicates truecolor. */
if (im->trueColor) {
gdPutWord (65534, out);
} else {
gdPutWord (65535, out);
}
gdPutWord (im->sx, out);
gdPutWord (im->sy, out);
_gdPutColors (im, out);
}
static void
_gdImageGd (gdImagePtr im, gdIOCtx * out)
{
int x, y;
_gdPutHeader (im, out);
for (y = 0; (y < im->sy); y++) {
for (x = 0; (x < im->sx); x++) {
/* ROW-MAJOR IN GD 1.3 */
if (im->trueColor) {
gdPutInt (im->tpixels[y][x], out);
} else {
gdPutC ((unsigned char) im->pixels[y][x], out);
}
}
}
}
/*
Function: gdImageGd
*/
BGD_DECLARE(void) gdImageGd (gdImagePtr im, FILE * outFile)
{
gdIOCtx *out = gdNewFileCtx (outFile);
if (out == NULL) return;
_gdImageGd (im, out);
out->gd_free (out);
}
/*
Function: gdImageGdPtr
*/
BGD_DECLARE(void *) gdImageGdPtr (gdImagePtr im, int *size)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
if (out == NULL) return NULL;
_gdImageGd (im, out);
rv = gdDPExtractData (out, size);
out->gd_free (out);
return rv;
}

1183
project/jni/gd/src/gd_gd2.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,751 @@
/**
* File: GIF Input
*
* Read GIF images.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
/* Used only when debugging GIF compression code */
/* #define DEBUGGING_ENVARS */
#ifdef DEBUGGING_ENVARS
static int verbose_set = 0;
static int verbose;
#define VERBOSE (verbose_set ? verbose : set_verbose())
static int set_verbose(void)
{
verbose = !!getenv("GIF_VERBOSE");
verbose_set = 1;
return(verbose);
}
#else
#define VERBOSE 0
#endif
#define MAXCOLORMAPSIZE 256
#define TRUE 1
#define FALSE 0
#define CM_RED 0
#define CM_GREEN 1
#define CM_BLUE 2
#define MAX_LWZ_BITS 12
#define INTERLACE 0x40
#define LOCALCOLORMAP 0x80
#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
#define ReadOK(file, buffer, len) (gdGetBuf(buffer, len, file) > 0)
#define LM_to_uint(a, b) (((b)<<8)|(a))
/* We may eventually want to use this information, but def it out for now */
#if 0
static struct {
unsigned int Width;
unsigned int Height;
unsigned char ColorMap[3][MAXCOLORMAPSIZE];
unsigned int BitPixel;
unsigned int ColorResolution;
unsigned int Background;
unsigned int AspectRatio;
} GifScreen;
#endif
#if 0
static struct {
int transparent;
int delayTime;
int inputFlag;
int disposal;
} Gif89 = { -1, -1, -1, 0 };
#endif
#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
#define CSD_BUF_SIZE 280
typedef struct {
unsigned char buf[CSD_BUF_SIZE];
int curbit;
int lastbit;
int done;
int last_byte;
} CODE_STATIC_DATA;
typedef struct {
int fresh;
int code_size, set_code_size;
int max_code, max_code_size;
int firstcode, oldcode;
int clear_code, end_code;
int table[2][(1<< MAX_LWZ_BITS)];
int stack[STACK_SIZE], *sp;
CODE_STATIC_DATA scd;
} LZW_STATIC_DATA;
static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
static int DoExtension (gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP);
static int GetDataBlock (gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP);
static int GetCode (gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP);
static int LWZReadByte (gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP);
static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP); /*1.4//, int ignore); */
/*
Function: gdImageCreateFromGif
<gdImageCreateFromGif> is called to load images from GIF format
files. Invoke <gdImageCreateFromGif> with an already opened
pointer to a file containing the desired
image.
<gdImageCreateFromGif> returns a <gdImagePtr> to the new image, or
NULL if unable to load the image (most often because the file is
corrupt or does not contain a GIF image). <gdImageCreateFromGif>
does not close the file. You can inspect the sx and sy members of
the image to determine its size. The image must eventually be
destroyed using <gdImageDestroy>.
Variants:
<gdImageCreateFromGifPtr> creates an image from GIF data (i.e. the
contents of a GIF file) already in memory.
<gdImageCreateFromGifCtx> reads in an image using the functions in
a <gdIOCtx> struct.
Parameters:
infile - The input FILE pointer
Returns:
A pointer to the new image or NULL if an error occurred.
Example:
> gdImagePtr im;
> ... inside a function ...
> FILE *in;
> in = fopen("mygif.gif", "rb");
> im = gdImageCreateFromGif(in);
> fclose(in);
> // ... Use the image ...
> gdImageDestroy(im);
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromGif(FILE *fdFile)
{
gdIOCtx *fd = gdNewFileCtx(fdFile);
gdImagePtr im;
if (fd == NULL) return NULL;
im = gdImageCreateFromGifCtx(fd);
fd->gd_free(fd);
return im;
}
/*
Function: gdImageCreateFromGifPtr
Parameters:
size - size of GIF data in bytes.
data - GIF data (i.e. contents of a GIF file).
See <gdImageCreateFromGif>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromGifPtr (int size, void *data)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
if(!in) {
return 0;
}
im = gdImageCreateFromGifCtx(in);
in->gd_free(in);
return im;
}
/*
Function: gdImageCreateFromGifCtx
See <gdImageCreateFromGif>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
{
int BitPixel;
#if 0
int ColorResolution;
int Background;
int AspectRatio;
#endif
int Transparent = (-1);
unsigned char buf[16];
unsigned char c;
unsigned char ColorMap[3][MAXCOLORMAPSIZE];
unsigned char localColorMap[3][MAXCOLORMAPSIZE];
int imw, imh, screen_width, screen_height;
int useGlobalColormap;
int bitPixel, i;
/*1.4//int imageCount = 0; */
/* 2.0.28: threadsafe storage */
int ZeroDataBlock = FALSE;
int haveGlobalColormap;
gdImagePtr im = 0;
memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE);
memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE);
if(!ReadOK(fd, buf, 6)) {
return 0;
}
if(strncmp((char *)buf, "GIF", 3) != 0) {
return 0;
}
if(memcmp((char *)buf + 3, "87a", 3) == 0) {
/* GIF87a */
} else if(memcmp((char *)buf + 3, "89a", 3) == 0) {
/* GIF89a */
} else {
return 0;
}
if(!ReadOK(fd, buf, 7)) {
return 0;
}
BitPixel = 2 << (buf[4] & 0x07);
#if 0
ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
Background = buf[5];
AspectRatio = buf[6];
#endif
screen_width = imw = LM_to_uint(buf[0], buf[1]);
screen_height = imh = LM_to_uint(buf[2], buf[3]);
haveGlobalColormap = BitSet(buf[4], LOCALCOLORMAP); /* Global Colormap */
if(haveGlobalColormap) {
if(ReadColorMap(fd, BitPixel, ColorMap)) {
return 0;
}
}
for (;;) {
int top, left;
int width, height;
if(!ReadOK(fd, &c, 1)) {
return 0;
}
if (c == ';') { /* GIF terminator */
goto terminated;
}
if(c == '!') { /* Extension */
if(!ReadOK(fd, &c, 1)) {
return 0;
}
DoExtension(fd, c, &Transparent, &ZeroDataBlock);
continue;
}
if(c != ',') { /* Not a valid start character */
continue;
}
/*1.4//++imageCount; */
if(!ReadOK(fd, buf, 9)) {
return 0;
}
useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);
bitPixel = 1 << ((buf[8] & 0x07) + 1);
left = LM_to_uint(buf[0], buf[1]);
top = LM_to_uint(buf[2], buf[3]);
width = LM_to_uint(buf[4], buf[5]);
height = LM_to_uint(buf[6], buf[7]);
if(((left + width) > screen_width) || ((top + height) > screen_height)) {
if(VERBOSE) {
printf("Frame is not confined to screen dimension.\n");
}
return 0;
}
if(!(im = gdImageCreate(width, height))) {
return 0;
}
im->interlace = BitSet(buf[8], INTERLACE);
if(!useGlobalColormap) {
if(ReadColorMap(fd, bitPixel, localColorMap)) {
gdImageDestroy(im);
return 0;
}
ReadImage(im, fd, width, height, localColorMap, BitSet(buf[8], INTERLACE), &ZeroDataBlock);
} else {
if(!haveGlobalColormap) {
gdImageDestroy(im);
return 0;
}
ReadImage(im, fd, width, height, ColorMap, BitSet(buf[8], INTERLACE), &ZeroDataBlock);
}
if(Transparent != (-1)) {
gdImageColorTransparent(im, Transparent);
}
goto terminated;
}
terminated:
/* Terminator before any image was declared! */
if(!im) {
return 0;
}
if(!im->colorsTotal) {
gdImageDestroy(im);
return 0;
}
/* Check for open colors at the end, so
* we can reduce colorsTotal and ultimately
* BitsPerPixel */
for(i = im->colorsTotal - 1; i >= 0; i--) {
if(im->open[i]) {
im->colorsTotal--;
} else {
break;
}
}
return im;
}
static int
ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256])
{
int i;
unsigned char rgb[3];
for(i = 0; i < number; ++i) {
if(!ReadOK(fd, rgb, sizeof(rgb))) {
return TRUE;
}
buffer[CM_RED][i] = rgb[0];
buffer[CM_GREEN][i] = rgb[1];
buffer[CM_BLUE][i] = rgb[2];
}
return FALSE;
}
static int
DoExtension(gdIOCtx *fd, int label, int *Transparent, int *ZeroDataBlockP)
{
unsigned char buf[256];
switch(label) {
case 0xf9: /* Graphic Control Extension */
memset(buf, 0, 4); /* initialize a few bytes in the case the next function fails */
(void) GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP);
#if 0
Gif89.disposal = (buf[0] >> 2) & 0x7;
Gif89.inputFlag = (buf[0] >> 1) & 0x1;
Gif89.delayTime = LM_to_uint(buf[1], buf[2]);
#endif
if((buf[0] & 0x1) != 0) {
*Transparent = buf[3];
}
while(GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
return FALSE;
default:
break;
}
while(GetDataBlock(fd, (unsigned char*) buf, ZeroDataBlockP) > 0);
return FALSE;
}
static int
GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
{
unsigned char count;
if(!ReadOK(fd, &count, 1)) {
return -1;
}
*ZeroDataBlockP = count == 0;
if((count != 0) && (!ReadOK(fd, buf, count))) {
return -1;
}
return count;
}
static int
GetDataBlock(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
{
int rv, i;
rv = GetDataBlock_(fd,buf, ZeroDataBlockP);
if(VERBOSE) {
printf("[GetDataBlock returning %d",rv);
if(rv > 0) {
printf(":");
for(i = 0; i < rv; i++) {
printf(" %02x",buf[i]);
}
}
printf("]\n");
}
return rv;
}
static int
GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
int i, j, ret;
unsigned char count;
if(flag) {
scd->curbit = 0;
scd->lastbit = 0;
scd->last_byte = 2;
scd->done = FALSE;
return 0;
}
if((scd->curbit + code_size) >= scd->lastbit) {
if(scd->done) {
if(scd->curbit >= scd->lastbit) {
/* Oh well */
}
return -1;
}
scd->buf[0] = scd->buf[scd->last_byte - 2];
scd->buf[1] = scd->buf[scd->last_byte - 1];
if((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0) {
scd->done = TRUE;
}
scd->last_byte = 2 + count;
scd->curbit = (scd->curbit - scd->lastbit) + 16;
scd->lastbit = (2 + count) * 8;
}
if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) {
ret = -1;
} else {
ret = 0;
for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) {
ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j;
}
}
scd->curbit += code_size;
return ret;
}
static int
GetCode(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
int rv;
rv = GetCode_(fd, scd, code_size,flag, ZeroDataBlockP);
if(VERBOSE) {
printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
}
return rv;
}
static int
LWZReadByte_(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{
int code, incode, i;
if(flag) {
sd->set_code_size = input_code_size;
sd->code_size = sd->set_code_size + 1;
sd->clear_code = 1 << sd->set_code_size;
sd->end_code = sd->clear_code + 1;
sd->max_code_size = 2 * sd->clear_code;
sd->max_code = sd->clear_code + 2;
GetCode(fd, &sd->scd, 0, TRUE, ZeroDataBlockP);
sd->fresh = TRUE;
for(i = 0; i < sd->clear_code; ++i) {
sd->table[0][i] = 0;
sd->table[1][i] = i;
}
for(; i < (1 << MAX_LWZ_BITS); ++i) {
sd->table[0][i] = sd->table[1][0] = 0;
}
sd->sp = sd->stack;
return 0;
} else if(sd->fresh) {
sd->fresh = FALSE;
do {
sd->firstcode = sd->oldcode =
GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
} while(sd->firstcode == sd->clear_code);
return sd->firstcode;
}
if(sd->sp > sd->stack) {
return *--sd->sp;
}
while((code = GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP)) >= 0) {
if(code == sd->clear_code) {
for(i = 0; i < sd->clear_code; ++i) {
sd->table[0][i] = 0;
sd->table[1][i] = i;
}
for (; i < (1 << MAX_LWZ_BITS); ++i) {
sd->table[0][i] = sd->table[1][i] = 0;
}
sd->code_size = sd->set_code_size + 1;
sd->max_code_size = 2 * sd->clear_code;
sd->max_code = sd->clear_code + 2;
sd->sp = sd->stack;
sd->firstcode = sd->oldcode =
GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
return sd->firstcode;
} else if(code == sd->end_code) {
int count;
unsigned char buf[260];
if(*ZeroDataBlockP) {
return -2;
}
while((count = GetDataBlock(fd, buf, ZeroDataBlockP)) > 0);
if(count != 0) {
return -2;
}
}
incode = code;
if(sd->sp == (sd->stack + STACK_SIZE)) {
/* Bad compressed data stream */
return -1;
}
if(code >= sd->max_code) {
*sd->sp++ = sd->firstcode;
code = sd->oldcode;
}
while(code >= sd->clear_code) {
if(sd->sp == (sd->stack + STACK_SIZE)) {
/* Bad compressed data stream */
return -1;
}
*sd->sp++ = sd->table[1][code];
if(code == sd->table[0][code]) {
/* Oh well */
}
code = sd->table[0][code];
}
*sd->sp++ = sd->firstcode = sd->table[1][code];
if((code = sd->max_code) < (1 << MAX_LWZ_BITS)) {
sd->table[0][code] = sd->oldcode;
sd->table[1][code] = sd->firstcode;
++sd->max_code;
if((sd->max_code >= sd->max_code_size) && (sd->max_code_size < (1<<MAX_LWZ_BITS))) {
sd->max_code_size *= 2;
++sd->code_size;
}
}
sd->oldcode = incode;
if(sd->sp > sd->stack) {
return *--sd->sp;
}
}
return code;
}
static int
LWZReadByte(gdIOCtx *fd, LZW_STATIC_DATA *sd, char flag, int input_code_size, int *ZeroDataBlockP)
{
int rv;
rv = LWZReadByte_(fd, sd, flag, input_code_size, ZeroDataBlockP);
if(VERBOSE) {
printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
}
return rv;
}
static void
ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP) /*1.4//, int ignore) */
{
unsigned char c;
int xpos = 0, ypos = 0, pass = 0;
int v, i;
LZW_STATIC_DATA sd;
/* Initialize the Compression routines */
if(!ReadOK(fd, &c, 1)) {
return;
}
if(c > MAX_LWZ_BITS) {
return;
}
/* Stash the color map into the image */
for(i=0; (i < gdMaxColors); i++) {
im->red[i] = cmap[CM_RED][i];
im->green[i] = cmap[CM_GREEN][i];
im->blue[i] = cmap[CM_BLUE][i];
im->open[i] = 1;
}
/* Many (perhaps most) of these colors will remain marked open. */
im->colorsTotal = gdMaxColors;
if(LWZReadByte(fd, &sd, TRUE, c, ZeroDataBlockP) < 0) {
return;
}
/*
** If this is an "uninteresting picture" ignore it.
** REMOVED For 1.4
*/
/*if (ignore) { */
/* while (LWZReadByte(fd, &sd, FALSE, c) >= 0) */
/* ; */
/* return; */
/*} */
while((v = LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP)) >= 0 ) {
if(v >= gdMaxColors) {
v = 0;
}
/* This how we recognize which colors are actually used. */
if(im->open[v]) {
im->open[v] = 0;
}
gdImageSetPixel(im, xpos, ypos, v);
++xpos;
if(xpos == len) {
xpos = 0;
if(interlace) {
switch (pass) {
case 0:
case 1:
ypos += 8;
break;
case 2:
ypos += 4;
break;
case 3:
ypos += 2;
break;
}
if(ypos >= height) {
++pass;
switch (pass) {
case 1:
ypos = 4;
break;
case 2:
ypos = 2;
break;
case 3:
ypos = 1;
break;
default:
goto fini;
}
}
} else {
++ypos;
}
}
if(ypos >= height) {
break;
}
}
fini:
if(LWZReadByte(fd, &sd, FALSE, c, ZeroDataBlockP) >=0) {
/* Ignore extra */
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
#ifndef GD_INTERN_H
#define GD_INTERN_H
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# elif defined(MAX_PATH)
# define MAXPATHLEN MAX_PATH
# else
# if defined(__GNU__)
# define MAXPATHLEN 4096
# else
# define MAXPATHLEN 256 /* Should be safe for any weird systems that do not define it */
# endif
# endif
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#else
# if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
# else
# include "msinttypes/inttypes.h"
# endif
#endif
#include "gd.h"
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))
#ifndef MAX
#define MAX(a,b) ((a)<(b)?(b):(a))
#endif
#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))
typedef enum {
HORIZONTAL,
VERTICAL,
} gdAxis;
/* Convert a double to an unsigned char, rounding to the nearest
* integer and clamping the result between 0 and max. The absolute
* value of clr must be less than the maximum value of an unsigned
* short. */
static inline unsigned char
uchar_clamp(double clr, unsigned char max) {
unsigned short result;
//assert(fabs(clr) <= SHRT_MAX);
/* Casting a negative float to an unsigned short is undefined.
* However, casting a float to a signed truncates toward zero and
* casting a negative signed value to an unsigned of the same size
* results in a bit-identical value (assuming twos-complement
* arithmetic). This is what we want: all legal negative values
* for clr will be greater than 255. */
/* Convert and clamp. */
result = (unsigned short)(short)(clr + 0.5);
if (result > max) {
result = (clr < 0) ? 0 : max;
}/* if */
return result;
}/* uchar_clamp*/
/* Internal prototypes: */
/* gd_rotate.c */
gdImagePtr gdImageRotate90(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
#endif

File diff suppressed because it is too large Load Diff

228
project/jni/gd/src/gd_io.c Normal file
View File

@@ -0,0 +1,228 @@
/*
* io.c
*
* Implements the simple I/O 'helper' routines.
*
* Not really essential, but these routines were used extensively in GD,
* so they were moved here. They also make IOCtx calls look better...
*
* Written (or, at least, moved) 1999, Philip Warner.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
/* Use this for commenting out debug-print statements. */
/* Just use the first '#define' to allow all the prints... */
/*#define IO_DBG(s) (s) */
#define IO_DBG(s)
#define GD_IO_EOF_CHK(r) \
if(r == EOF) { \
return 0; \
}
/*
* Write out a word to the I/O context pointer
*/
void Putword(int w, gdIOCtx *ctx)
{
unsigned char buf[2];
buf[0] = w & 0xff;
buf[1] = (w / 256) & 0xff;
(ctx->putBuf)(ctx, (char *)buf, 2);
}
void Putchar(int c, gdIOCtx *ctx)
{
(ctx->putC)(ctx, c & 0xff);
}
void gdPutC(const unsigned char c, gdIOCtx *ctx)
{
(ctx->putC)(ctx, c);
}
void gdPutWord (int w, gdIOCtx *ctx)
{
IO_DBG(printf("Putting word...\n"));
(ctx->putC)(ctx, (unsigned char)(w >> 8));
(ctx->putC)(ctx, (unsigned char)(w & 0xFF));
IO_DBG(printf("put.\n"));
}
void gdPutInt (int w, gdIOCtx *ctx)
{
IO_DBG(printf("Putting int...\n"));
(ctx->putC)(ctx, (unsigned char) (w >> 24));
(ctx->putC)(ctx, (unsigned char) ((w >> 16) & 0xFF));
(ctx->putC)(ctx, (unsigned char) ((w >> 8) & 0xFF));
(ctx->putC)(ctx, (unsigned char) (w & 0xFF));
IO_DBG(printf("put.\n"));
}
int gdGetC(gdIOCtx *ctx)
{
return ((ctx->getC)(ctx));
}
int gdGetByte(int *result, gdIOCtx *ctx)
{
int r;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result = r;
return 1;
}
int gdGetWord(int *result, gdIOCtx *ctx)
{
int r;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result = r << 8;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result += r;
return 1;
}
int gdGetWordLSB(signed short int *result, gdIOCtx *ctx)
{
int high = 0, low = 0;
low = (ctx->getC) (ctx);
if (low == EOF) {
return 0;
}
high = (ctx->getC) (ctx);
if (high == EOF) {
return 0;
}
if (result) {
*result = (high << 8) | low;
}
return 1;
}
int gdGetInt(int *result, gdIOCtx *ctx)
{
int r;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result = r << 24;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result += r << 16;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result += r << 8;
r = (ctx->getC)(ctx);
if(r == EOF) {
return 0;
}
*result += r;
return 1;
}
int gdGetIntLSB(signed int *result, gdIOCtx *ctx)
{
int c = 0;
unsigned int r = 0;
c = (ctx->getC) (ctx);
if (c == EOF) {
return 0;
}
r |= (c << 24);
r >>= 8;
c = (ctx->getC) (ctx);
if (c == EOF) {
return 0;
}
r |= (c << 24);
r >>= 8;
c = (ctx->getC) (ctx);
if (c == EOF) {
return 0;
}
r |= (c << 24);
r >>= 8;
c = (ctx->getC) (ctx);
if (c == EOF) {
return 0;
}
r |= (c << 24);
if (result) {
*result = (signed int)r;
}
return 1;
}
int gdPutBuf(const void *buf, int size, gdIOCtx *ctx)
{
IO_DBG(printf("Putting buf...\n"));
return (ctx->putBuf)(ctx, buf, size);
IO_DBG(printf("put.\n"));
}
int gdGetBuf(void *buf, int size, gdIOCtx *ctx)
{
return (ctx->getBuf)(ctx, buf, size);
}
int gdSeek(gdIOCtx *ctx, const int pos)
{
IO_DBG(printf("Seeking...\n"));
return ((ctx->seek)(ctx, pos));
IO_DBG(printf("Done.\n"));
}
long gdTell(gdIOCtx *ctx)
{
IO_DBG(printf("Telling...\n"));
return ((ctx->tell)(ctx));
IO_DBG(printf("told.\n"));
}

View File

@@ -0,0 +1,431 @@
/*
* io_dp.c
*
* Implements the dynamic pointer interface.
*
* Based on GD.pm code by Lincoln Stein for interfacing to libgd.
* Added support for reading as well as support for 'tell' and 'seek'.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* gdDPExtractData is the exception to this: it will return the pointer to
* the internal data, and reset the internal storage.
*
* Written/Modified 1999, Philip Warner.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "gdhelpers.h"
#define TRUE 1
#define FALSE 0
/* this is used for creating images in main memory */
typedef struct dpStruct {
void *data;
int logicalSize;
int realSize;
int dataGood;
int pos;
int freeOK;
}
dynamicPtr;
typedef struct dpIOCtx {
gdIOCtx ctx;
dynamicPtr *dp;
}
dpIOCtx;
typedef struct dpIOCtx *dpIOCtxPtr;
/* these functions operate on in-memory dynamic pointers */
static int allocDynamic(dynamicPtr *dp, int initialSize, void *data);
static int appendDynamic(dynamicPtr *dp, const void *src, int size);
static int gdReallocDynamic(dynamicPtr *dp, int required);
static int trimDynamic(dynamicPtr *dp);
static void gdFreeDynamicCtx(struct gdIOCtx *ctx);
static dynamicPtr *newDynamic(int initialSize, void *data, int freeOKFlag);
static int dynamicPutbuf(struct gdIOCtx *, const void *, int);
static void dynamicPutchar(struct gdIOCtx *, int a);
static int dynamicGetbuf(gdIOCtxPtr ctx, void *buf, int len);
static int dynamicGetchar(gdIOCtxPtr ctx);
static int dynamicSeek(struct gdIOCtx *, const int);
static long dynamicTell(struct gdIOCtx *);
/*
Function: gdNewDynamicCtx
Return data as a dynamic pointer.
*/
BGD_DECLARE(gdIOCtx *) gdNewDynamicCtx(int initialSize, void *data)
{
/* 2.0.23: Phil Moore: 'return' keyword was missing! */
return gdNewDynamicCtxEx(initialSize, data, 1);
}
/*
Function: gdNewDynamicCtxEx
*/
BGD_DECLARE(gdIOCtx *) gdNewDynamicCtxEx(int initialSize, void *data, int freeOKFlag)
{
dpIOCtx *ctx;
dynamicPtr *dp;
ctx = (dpIOCtx *)gdMalloc(sizeof (dpIOCtx));
if(ctx == NULL) {
return NULL;
}
dp = newDynamic(initialSize, data, freeOKFlag);
if(!dp) {
gdFree (ctx);
return NULL;
};
ctx->dp = dp;
ctx->ctx.getC = dynamicGetchar;
ctx->ctx.putC = dynamicPutchar;
ctx->ctx.getBuf = dynamicGetbuf;
ctx->ctx.putBuf = dynamicPutbuf;
ctx->ctx.seek = dynamicSeek;
ctx->ctx.tell = dynamicTell;
ctx->ctx.gd_free = gdFreeDynamicCtx;
return (gdIOCtx *)ctx;
}
/*
Function: gdDPExtractData
*/
BGD_DECLARE(void *) gdDPExtractData (struct gdIOCtx *ctx, int *size)
{
dynamicPtr *dp;
dpIOCtx *dctx;
void *data;
dctx = (dpIOCtx *)ctx;
dp = dctx->dp;
/* clean up the data block and return it */
if(dp->dataGood) {
trimDynamic(dp);
*size = dp->logicalSize;
data = dp->data;
} else {
*size = 0;
data = NULL;
/* 2.0.21: never free memory we don't own */
if((dp->data != NULL) && (dp->freeOK)) {
gdFree(dp->data);
}
}
dp->data = NULL;
dp->realSize = 0;
dp->logicalSize = 0;
return data;
}
static void gdFreeDynamicCtx(struct gdIOCtx *ctx)
{
dynamicPtr *dp;
dpIOCtx *dctx;
dctx = (dpIOCtx *)ctx;
dp = dctx->dp;
gdFree(ctx);
/* clean up the data block and return it */
/* 2.0.21: never free memory we don't own */
if((dp->data != NULL) && (dp->freeOK)) {
gdFree(dp->data);
dp->data = NULL;
}
dp->realSize = 0;
dp->logicalSize = 0;
gdFree(dp);
}
static long dynamicTell(struct gdIOCtx *ctx)
{
dpIOCtx *dctx;
dctx = (dpIOCtx *)ctx;
return (dctx->dp->pos);
}
static int dynamicSeek(struct gdIOCtx *ctx, const int pos)
{
int bytesNeeded;
dynamicPtr *dp;
dpIOCtx *dctx;
if (pos < 0) {
return FALSE;
}
dctx = (dpIOCtx *)ctx;
dp = dctx->dp;
if(!dp->dataGood) {
return FALSE;
}
bytesNeeded = pos;
if(bytesNeeded > dp->realSize) {
/* 2.0.21 */
if(!dp->freeOK) {
return FALSE;
}
if(overflow2(dp->realSize, 2)) {
return FALSE;
}
if(!gdReallocDynamic(dp, dp->realSize * 2)) {
dp->dataGood = FALSE;
return FALSE;
}
}
/* if we get here, we can be sure that we have enough bytes
* to copy safely */
/* Extend the logical size if we seek beyond EOF. */
if(pos > dp->logicalSize) {
dp->logicalSize = pos;
};
dp->pos = pos;
return TRUE;
}
/* return data as a dynamic pointer */
static dynamicPtr *newDynamic(int initialSize, void *data, int freeOKFlag)
{
dynamicPtr *dp;
dp = (dynamicPtr *) gdMalloc(sizeof (dynamicPtr));
if(dp == NULL) {
return NULL;
}
if(!allocDynamic(dp, initialSize, data)) {
gdFree(dp);
return NULL;
}
dp->pos = 0;
dp->freeOK = freeOKFlag;
return dp;
}
static int dynamicPutbuf(struct gdIOCtx *ctx, const void *buf, int size)
{
dpIOCtx *dctx;
dctx = (dpIOCtx *)ctx;
appendDynamic(dctx->dp, buf, size);
if(dctx->dp->dataGood) {
return size;
} else {
return -1;
};
}
static void dynamicPutchar(struct gdIOCtx *ctx, int a)
{
unsigned char b;
dpIOCtxPtr dctx;
b = a;
dctx = (dpIOCtxPtr) ctx;
appendDynamic(dctx->dp, &b, 1);
}
/* returns the number of bytes actually read; 0 on EOF and error */
static int dynamicGetbuf(gdIOCtxPtr ctx, void *buf, int len)
{
int rlen, remain;
dpIOCtxPtr dctx;
dynamicPtr *dp;
dctx = (dpIOCtxPtr) ctx;
dp = dctx->dp;
if (dp->pos < 0 || dp->pos >= dp->realSize) {
return 0;
}
remain = dp->logicalSize - dp->pos;
if(remain >= len) {
rlen = len;
} else {
if(remain <= 0) {
return 0;
}
rlen = remain;
}
if (dp->pos + rlen > dp->realSize) {
rlen = dp->realSize - dp->pos;
}
if (rlen < 0) {
return 0;
}
memcpy(buf, (void *) ((char *)dp->data + dp->pos), rlen);
dp->pos += rlen;
return rlen;
}
static int dynamicGetchar(gdIOCtxPtr ctx)
{
unsigned char b;
int rv;
rv = dynamicGetbuf(ctx, &b, 1);
if(rv != 1) {
return EOF;
} else {
return b; /* (b & 0xff); */
}
}
/**********************************************************************
* InitDynamic - Return a dynamically resizable void*
**********************************************************************/
static int allocDynamic(dynamicPtr *dp, int initialSize, void *data)
{
if(data == NULL) {
dp->logicalSize = 0;
dp->dataGood = FALSE;
dp->data = gdMalloc(initialSize);
} else {
dp->logicalSize = initialSize;
dp->dataGood = TRUE;
dp->data = data;
}
if(dp->data != NULL) {
dp->realSize = initialSize;
dp->dataGood = TRUE;
dp->pos = 0;
return TRUE;
} else {
dp->realSize = 0;
return FALSE;
}
}
/* append bytes to the end of a dynamic pointer */
static int appendDynamic(dynamicPtr * dp, const void *src, int size)
{
int bytesNeeded;
char *tmp;
if(!dp->dataGood) {
return FALSE;
}
/* bytesNeeded = dp->logicalSize + size; */
bytesNeeded = dp->pos + size;
if(bytesNeeded > dp->realSize) {
/* 2.0.21 */
if(!dp->freeOK) {
return FALSE;
}
if(overflow2(dp->realSize, 2)) {
return FALSE;
}
if(!gdReallocDynamic(dp, bytesNeeded * 2)) {
dp->dataGood = FALSE;
return FALSE;
}
}
/* if we get here, we can be sure that we have enough bytes
* to copy safely */
/*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
tmp = (char *)dp->data;
memcpy ((void *)(tmp + (dp->pos)), src, size);
dp->pos += size;
if(dp->pos > dp->logicalSize) {
dp->logicalSize = dp->pos;
};
return TRUE;
}
/* grow (or shrink) dynamic pointer */
static int gdReallocDynamic(dynamicPtr *dp, int required)
{
void *newPtr;
/* First try gdRealloc(). If that doesn't work, make a new
* memory block and copy. */
if((newPtr = gdRealloc(dp->data, required))) {
dp->realSize = required;
dp->data = newPtr;
return TRUE;
}
/* create a new pointer */
newPtr = gdMalloc(required);
if(!newPtr) {
dp->dataGood = FALSE;
return FALSE;
}
/* copy the old data into it */
memcpy(newPtr, dp->data, dp->logicalSize);
gdFree(dp->data);
dp->data = newPtr;
dp->realSize = required;
return TRUE;
}
/* trim pointer so that its real and logical sizes match */
static int trimDynamic(dynamicPtr *dp)
{
/* 2.0.21: we don't reallocate memory we don't own */
if(!dp->freeOK) {
return TRUE;
}
return gdReallocDynamic(dp, dp->logicalSize);
}

View File

@@ -0,0 +1,136 @@
/*
* io_file.c
*
* Implements the file interface.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* Most functions are just 'wrappers' for standard file functions.
*
* Written/Modified 1999, Philip Warner.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/* For platforms with incomplete ANSI defines. Fortunately,
* SEEK_SET is defined to be zero by the standard. */
#ifndef SEEK_SET
# define SEEK_SET 0
#endif /* SEEK_SET */
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "gdhelpers.h"
/* this is used for creating images in main memory */
typedef struct fileIOCtx {
gdIOCtx ctx;
FILE *f;
}
fileIOCtx;
gdIOCtx *newFileCtx(FILE *f);
static int fileGetbuf(gdIOCtx *, void *, int);
static int filePutbuf(gdIOCtx *, const void *, int);
static void filePutchar(gdIOCtx *, int);
static int fileGetchar(gdIOCtx *ctx);
static int fileSeek(struct gdIOCtx *, const int);
static long fileTell(struct gdIOCtx *);
static void gdFreeFileCtx(gdIOCtx *ctx);
/*
Function: gdNewFileCtx
Return data as a dynamic pointer.
*/
BGD_DECLARE(gdIOCtx *) gdNewFileCtx(FILE *f)
{
fileIOCtx *ctx;
if (f == NULL) return NULL;
ctx = (fileIOCtx *)gdMalloc(sizeof(fileIOCtx));
if(ctx == NULL) {
return NULL;
}
ctx->f = f;
ctx->ctx.getC = fileGetchar;
ctx->ctx.putC = filePutchar;
ctx->ctx.getBuf = fileGetbuf;
ctx->ctx.putBuf = filePutbuf;
ctx->ctx.tell = fileTell;
ctx->ctx.seek = fileSeek;
ctx->ctx.gd_free = gdFreeFileCtx;
return (gdIOCtx *)ctx;
}
static void gdFreeFileCtx(gdIOCtx *ctx)
{
gdFree(ctx);
}
static int filePutbuf(gdIOCtx *ctx, const void *buf, int size)
{
fileIOCtx *fctx;
fctx = (fileIOCtx *)ctx;
return fwrite(buf, 1, size, fctx->f);
}
static int fileGetbuf(gdIOCtx *ctx, void *buf, int size)
{
fileIOCtx *fctx;
fctx = (fileIOCtx *)ctx;
return (fread(buf, 1, size, fctx->f));
}
static void filePutchar(gdIOCtx *ctx, int a)
{
unsigned char b;
fileIOCtx *fctx;
fctx = (fileIOCtx *)ctx;
b = a;
putc(b, fctx->f);
}
static int fileGetchar(gdIOCtx *ctx)
{
fileIOCtx *fctx;
fctx = (fileIOCtx *)ctx;
return getc(fctx->f);
}
static int fileSeek(struct gdIOCtx *ctx, const int pos)
{
fileIOCtx *fctx;
fctx = (fileIOCtx *)ctx;
return (fseek(fctx->f, pos, SEEK_SET) == 0);
}
static long fileTell (struct gdIOCtx *ctx)
{
fileIOCtx *fctx;
fctx = (fileIOCtx *)ctx;
return ftell(fctx->f);
}

View File

@@ -0,0 +1,146 @@
/*
* io_ss.c
*
* Implements the Source/Sink interface.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* The Source/Sink model is the primary 'user' interface for alternate data
* sources; the IOCtx interface is intended (at least in version 1.5) to be
* used internally until it settles down a bit.
*
* This module just layers the Source/Sink interface on top of the IOCtx; no
* support is provided for tell/seek, so GD2 writing is not possible, and
* retrieving parts of GD2 files is also not possible.
*
* A new SS context does not need to be created with both a Source and a Sink.
*
* Written/Modified 1999, Philip Warner.
*
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "gdhelpers.h"
/* this is used for creating images in main memory */
typedef struct ssIOCtx {
gdIOCtx ctx;
gdSourcePtr src;
gdSinkPtr snk;
}
ssIOCtx;
typedef struct ssIOCtx *ssIOCtxPtr;
static int sourceGetbuf(gdIOCtx *, void *, int);
static int sourceGetchar(gdIOCtx *ctx);
static int sinkPutbuf(gdIOCtx *ctx, const void *buf, int size);
static void sinkPutchar(gdIOCtx *ctx, int a);
static void gdFreeSsCtx(gdIOCtx *ctx);
/*
Function: gdNewSSCtx
Return data as a dynamic pointer.
*/
BGD_DECLARE(gdIOCtx *) gdNewSSCtx(gdSourcePtr src, gdSinkPtr snk)
{
ssIOCtxPtr ctx;
ctx = (ssIOCtxPtr)gdMalloc(sizeof (ssIOCtx));
if (ctx == NULL) {
return NULL;
}
ctx->src = src;
ctx->snk = snk;
ctx->ctx.getC = sourceGetchar;
ctx->ctx.getBuf = sourceGetbuf;
ctx->ctx.putC = sinkPutchar;
ctx->ctx.putBuf = sinkPutbuf;
ctx->ctx.tell = NULL;
ctx->ctx.seek = NULL;
ctx->ctx.gd_free = gdFreeSsCtx;
return (gdIOCtx *)ctx;
}
static void gdFreeSsCtx(gdIOCtx *ctx)
{
gdFree(ctx);
}
static int sourceGetbuf(gdIOCtx *ctx, void *buf, int size)
{
ssIOCtx *lctx;
int res;
lctx = (ssIOCtx *)ctx;
res = ((lctx->src->source)(lctx->src->context, buf, size));
/*
* Translate the return values from the Source object:
* 0 is EOF, -1 is error
*/
if (res == 0) {
return 0;
} else if (res < 0) {
return 0;
} else {
return res;
}
}
static int sourceGetchar(gdIOCtx *ctx)
{
int res;
unsigned char buf;
res = sourceGetbuf(ctx, &buf, 1);
if (res == 1) {
return buf;
} else {
return EOF;
}
}
static int sinkPutbuf(gdIOCtx *ctx, const void *buf, int size)
{
ssIOCtxPtr lctx;
int res;
lctx = (ssIOCtx *)ctx;
res = (lctx->snk->sink)(lctx->snk->context, buf, size);
if (res <= 0) {
return 0;
} else {
return res;
}
}
static void sinkPutchar(gdIOCtx *ctx, int a)
{
unsigned char b;
b = a;
sinkPutbuf(ctx, &b, 1);
}

View File

@@ -0,0 +1,126 @@
/* *****************************************************************************
** $Id$
** Initial file written and documented by:
** Kevin Shepherd <kshepherd@php.net> December 2007
** of Scarlet Line http://www.scarletline.com/
*******************************************************************************/
/** \file gd_io_stream.h
\brief C++ standard library iostream specializations of gdIOCtx.
Note that all of the methods defined in this header are internal to the
libgd library, except for the constructors.
Only the constructors are needed by a user of the libgd API.
This file does not use or need gdpp.h, but if GD::Image is
used, then C++ coding becomes even simpler, and the classes below
become entirely hidden implementation details.
Example usage, convert png to gif:
#include <fstream>
#include "gd_io_stream.h"
std::ifstream in("image.png", std::ios_base::in | std::ios_base::binary );
if (in.good())
{
istreamIOCtx _in_ctx(in);
gdImagePtr im_in = gdImageCreateFromPngCtx ( & _in_ctx);
std::ofstream out("image.gif", std::ios_base::out | std::ios_base::binary );
ostreamIOCtx _out_ctx(out);
gdImageGifCtx(im_in, & _out_ctx);
}
gdImageDestroy(im_in);
*/
#ifdef __cplusplus
#ifndef _gd_io_stream_h
#define _gd_io_stream_h
#include "gd.h"
#include <iostream>
/** Standard library input stream specialization of gdIOCtx
*/
class BGD_EXPORT_DATA_IMPL istreamIOCtx : public gdIOCtx
{
public:
typedef std::istream stream_type;
/** Construct an instance of this input stream specialization,
given an input stream.
For example:
std::ifstream in("image.png", std::ios_base::in | std::ios_base::binary );
istreamIOCtx in_ctx(in);
*/
istreamIOCtx(stream_type & __stream) {
init( & __stream);
}
static int Getbuf (struct gdIOCtx * ctx, void * buf, int size);
static int Putbuf (struct gdIOCtx * , const void * , int );
static void Putchar (struct gdIOCtx * , int );
static int Getchar (struct gdIOCtx * ctx);
static int Seek (struct gdIOCtx * ctx, const int pos);
static long Tell (struct gdIOCtx * ctx);
static void FreeCtx (struct gdIOCtx * ctx);
void init(stream_type * __stream) {
getC = Getchar;
putC = Putchar;
getBuf = Getbuf;
putBuf = Putbuf;
tell = Tell;
seek = Seek;
gd_free = FreeCtx;
_M_stream = __stream;
}
private:
stream_type * _M_stream;
};
/** Allocate a new instance of the class
*/
inline gdIOCtx * gdNewIstreamCtx (std::istream * __stream)
{
return new istreamIOCtx(* __stream);
}
/** Standard library output stream specialization of gdIOCtx
*/
class BGD_EXPORT_DATA_IMPL ostreamIOCtx : public gdIOCtx
{
public:
typedef std::ostream stream_type;
/** Construct an instance of this output stream specialization,
given an output stream.
For example:
std::ofstream out("image.gif", std::ios_base::out | std::ios_base::binary );
ostreamIOCtx out_ctx(out);
*/
ostreamIOCtx(stream_type & __stream) {
init( & __stream);
}
static int Getbuf (struct gdIOCtx * , void * , int );
static int Putbuf (struct gdIOCtx * ctx, const void * buf, int size);
static int Getchar (struct gdIOCtx * );
static void Putchar (struct gdIOCtx * ctx, int a);
static int Seek (struct gdIOCtx * ctx, const int pos);
static long Tell (struct gdIOCtx * ctx);
static void FreeCtx (struct gdIOCtx * ctx);
void init(stream_type * __stream) {
getC = Getchar;
putC = Putchar;
getBuf = Getbuf;
putBuf = Putbuf;
tell = Tell;
seek = Seek;
gd_free = FreeCtx;
_M_stream = __stream;
}
private:
stream_type * _M_stream;
};
/** Allocate a new instance of the class
*/
inline gdIOCtx * gdNewOstreamCtx (std::ostream * __stream)
{
return new ostreamIOCtx(* __stream);
}
#endif /* _gd_io_stream_h */
#endif /* __cplusplus */

1201
project/jni/gd/src/gd_jpeg.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,336 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "gd.h"
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
/**
* Title: Matrix
* Group: Affine Matrix
*/
/**
* Function: gdAffineApplyToPointF
* Applies an affine transformation to a point (floating point
* gdPointF)
*
*
* Parameters:
* dst - Where to store the resulting point
* affine - Source Point
* flip_horz - affine matrix
*
* Returns:
* GD_TRUE if the affine is rectilinear or GD_FALSE
*/
BGD_DECLARE(int) gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src,
const double affine[6])
{
double x = src->x;
double y = src->y;
dst->x = x * affine[0] + y * affine[2] + affine[4];
dst->y = x * affine[1] + y * affine[3] + affine[5];
return GD_TRUE;
}
/**
* Function: gdAffineInvert
* Find the inverse of an affine transformation.
*
* All non-degenerate affine transforms are invertible. Applying the
* inverted matrix will restore the original values. Multiplying <src>
* by <dst> (commutative) will return the identity affine (rounding
* error possible).
*
* Parameters:
* dst - Where to store the resulting affine transform
* src_affine - Original affine matrix
* flip_horz - Whether or not to flip horizontally
* flip_vert - Whether or not to flip vertically
*
* See also:
* <gdAffineIdentity>
*
* Returns:
* GD_TRUE if the affine is rectilinear or GD_FALSE
*/
BGD_DECLARE(int) gdAffineInvert (double dst[6], const double src[6])
{
double r_det = (src[0] * src[3] - src[1] * src[2]);
if (r_det <= 0.0) {
return GD_FALSE;
}
r_det = 1.0 / r_det;
dst[0] = src[3] * r_det;
dst[1] = -src[1] * r_det;
dst[2] = -src[2] * r_det;
dst[3] = src[0] * r_det;
dst[4] = -src[4] * dst[0] - src[5] * dst[2];
dst[5] = -src[4] * dst[1] - src[5] * dst[3];
return GD_TRUE;
}
/**
* Function: gdAffineFlip
* Flip an affine transformation horizontally or vertically.
*
* Flips the affine transform, giving GD_FALSE for <flip_horz> and
* <flip_vert> will clone the affine matrix. GD_TRUE for both will
* copy a 180° rotation.
*
* Parameters:
* dst - Where to store the resulting affine transform
* src_affine - Original affine matrix
* flip_h - Whether or not to flip horizontally
* flip_v - Whether or not to flip vertically
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineFlip (double dst[6], const double src[6], const int flip_h, const int flip_v)
{
dst[0] = flip_h ? - src[0] : src[0];
dst[1] = flip_h ? - src[1] : src[1];
dst[2] = flip_v ? - src[2] : src[2];
dst[3] = flip_v ? - src[3] : src[3];
dst[4] = flip_h ? - src[4] : src[4];
dst[5] = flip_v ? - src[5] : src[5];
return GD_TRUE;
}
/**
* Function: gdAffineConcat
* Concat (Multiply) two affine transformation matrices.
*
* Concats two affine transforms together, i.e. the result
* will be the equivalent of doing first the transformation m1 and then
* m2. All parameters can be the same matrix (safe to call using
* the same array for all three arguments).
*
* Parameters:
* dst - Where to store the resulting affine transform
* m1 - First affine matrix
* m2 - Second affine matrix
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineConcat (double dst[6], const double m1[6], const double m2[6])
{
double dst0, dst1, dst2, dst3, dst4, dst5;
dst0 = m1[0] * m2[0] + m1[1] * m2[2];
dst1 = m1[0] * m2[1] + m1[1] * m2[3];
dst2 = m1[2] * m2[0] + m1[3] * m2[2];
dst3 = m1[2] * m2[1] + m1[3] * m2[3];
dst4 = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
dst5 = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
dst[0] = dst0;
dst[1] = dst1;
dst[2] = dst2;
dst[3] = dst3;
dst[4] = dst4;
dst[5] = dst5;
return GD_TRUE;
}
/**
* Function: gdAffineIdentity
* Set up the identity matrix.
*
* Parameters:
* dst - Where to store the resulting affine transform
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineIdentity (double dst[6])
{
dst[0] = 1;
dst[1] = 0;
dst[2] = 0;
dst[3] = 1;
dst[4] = 0;
dst[5] = 0;
return GD_TRUE;
}
/**
* Function: gdAffineScale
* Set up a scaling matrix.
*
* Parameters:
* scale_x - X scale factor
* scale_y - Y scale factor
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineScale (double dst[6], const double scale_x, const double scale_y)
{
dst[0] = scale_x;
dst[1] = 0;
dst[2] = 0;
dst[3] = scale_y;
dst[4] = 0;
dst[5] = 0;
return GD_TRUE;
}
/**
* Function: gdAffineRotate
* Set up a rotation affine transform.
*
* Like the other angle in libGD, in which increasing y moves
* downward, this is a counterclockwise rotation.
*
* Parameters:
* dst - Where to store the resulting affine transform
* angle - Rotation angle in degrees
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineRotate (double dst[6], const double angle)
{
const double sin_t = sin (angle * M_PI / 180.0);
const double cos_t = cos (angle * M_PI / 180.0);
dst[0] = cos_t;
dst[1] = sin_t;
dst[2] = -sin_t;
dst[3] = cos_t;
dst[4] = 0;
dst[5] = 0;
return GD_TRUE;
}
/**
* Function: gdAffineShearHorizontal
* Set up a horizontal shearing matrix || becomes \\.
*
* Parameters:
* dst - Where to store the resulting affine transform
* angle - Shear angle in degrees
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineShearHorizontal(double dst[6], const double angle)
{
dst[0] = 1;
dst[1] = 0;
dst[2] = tan(angle * M_PI / 180.0);
dst[3] = 1;
dst[4] = 0;
dst[5] = 0;
return GD_TRUE;
}
/**
* Function: gdAffineShearVertical
* Set up a vertical shearing matrix, columns are untouched.
*
* Parameters:
* dst - Where to store the resulting affine transform
* angle - Shear angle in degrees
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineShearVertical(double dst[6], const double angle)
{
dst[0] = 1;
dst[1] = tan(angle * M_PI / 180.0);
dst[2] = 0;
dst[3] = 1;
dst[4] = 0;
dst[5] = 0;
return GD_TRUE;
}
/**
* Function: gdAffineTranslate
* Set up a translation matrix.
*
* Parameters:
* dst - Where to store the resulting affine transform
* offset_x - Horizontal translation amount
* offset_y - Vertical translation amount
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineTranslate (double dst[6], const double offset_x, const double offset_y)
{
dst[0] = 1;
dst[1] = 0;
dst[2] = 0;
dst[3] = 1;
dst[4] = offset_x;
dst[5] = offset_y;
return GD_TRUE;
}
/**
* gdAffineexpansion: Find the affine's expansion factor.
* @src: The affine transformation.
*
* Finds the expansion factor, i.e. the square root of the factor
* by which the affine transform affects area. In an affine transform
* composed of scaling, rotation, shearing, and translation, returns
* the amount of scaling.
*
* GD_TRUE on success or GD_FALSE
**/
BGD_DECLARE(double) gdAffineExpansion (const double src[6])
{
return sqrt (fabs (src[0] * src[3] - src[1] * src[2]));
}
/**
* Function: gdAffineRectilinear
* Determines whether the affine transformation is axis aligned. A
* tolerance has been implemented using GD_EPSILON.
*
* Parameters:
* m - The affine transformation
*
* Returns:
* GD_TRUE if the affine is rectilinear or GD_FALSE
*/
BGD_DECLARE(int) gdAffineRectilinear (const double m[6])
{
return ((fabs (m[1]) < GD_EPSILON && fabs (m[2]) < GD_EPSILON) ||
(fabs (m[0]) < GD_EPSILON && fabs (m[3]) < GD_EPSILON));
}
/**
* Function: gdAffineEqual
* Determines whether two affine transformations are equal. A tolerance
* has been implemented using GD_EPSILON.
*
* Parameters:
* m1 - The first affine transformation
* m2 - The first affine transformation
*
* Returns:
* GD_TRUE on success or GD_FALSE
*/
BGD_DECLARE(int) gdAffineEqual (const double m1[6], const double m2[6])
{
return (fabs (m1[0] - m2[0]) < GD_EPSILON &&
fabs (m1[1] - m2[1]) < GD_EPSILON &&
fabs (m1[2] - m2[2]) < GD_EPSILON &&
fabs (m1[3] - m2[3]) < GD_EPSILON &&
fabs (m1[4] - m2[4]) < GD_EPSILON &&
fabs (m1[5] - m2[5]) < GD_EPSILON);
}

View File

@@ -0,0 +1,645 @@
/* NeuQuant Neural-Net Quantization Algorithm
* ------------------------------------------
*
* Copyright (c) 1994 Anthony Dekker
*
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML
*
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
*
*
* Modified to process 32bit RGBA images.
* Stuart Coyle 2004-2007
* From: http://pngnq.sourceforge.net/
*
* Ported to libgd by Pierre A. Joye
* (and make it thread safety by droping static and global variables)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdlib.h>
#include <string.h>
#include "gd.h"
#include "gdhelpers.h"
#include "gd_errors.h"
#include "gd_nnquant.h"
/* Network Definitions
------------------- */
#define maxnetpos (MAXNETSIZE-1)
#define netbiasshift 4 /* bias for colour values */
#define ncycles 100 /* no. of learning cycles */
/* defs for freq and bias */
#define intbiasshift 16 /* bias for fractions */
#define intbias (((int) 1)<<intbiasshift)
#define gammashift 10 /* gamma = 1024 */
#define gamma (((int) 1)<<gammashift)
#define betashift 10
#define beta (intbias>>betashift) /* beta = 1/1024 */
#define betagamma (intbias<<(gammashift-betashift))
/* defs for decreasing radius factor */
#define initrad (MAXNETSIZE>>3) /* for 256 cols, radius starts */
#define radiusbiasshift 6 /* at 32.0 biased by 6 bits */
#define radiusbias (((int) 1)<<radiusbiasshift)
#define initradius (initrad*radiusbias) /* and decreases by a */
#define radiusdec 30 /* factor of 1/30 each cycle */
/* defs for decreasing alpha factor */
#define alphabiasshift 10 /* alpha starts at 1.0 */
#define initalpha (((int) 1)<<alphabiasshift)
int alphadec;
/* radbias and alpharadbias used for radpower calculation */
#define radbiasshift 8
#define radbias (((int) 1)<<radbiasshift)
#define alpharadbshift (alphabiasshift+radbiasshift)
#define alpharadbias (((int) 1)<<alpharadbshift)
#define ALPHA 0
#define RED 1
#define BLUE 2
#define GREEN 3
typedef int nq_pixel[5];
typedef struct {
/* biased by 10 bits */
int alphadec;
/* lengthcount = H*W*3 */
int lengthcount;
/* sampling factor 1..30 */
int samplefac;
/* Number of colours to use. Made a global instead of #define */
int netsize;
/* for network lookup - really 256 */
int netindex[256];
/* ABGRc */
/* the network itself */
nq_pixel network[MAXNETSIZE];
/* bias and freq arrays for learning */
int bias[MAXNETSIZE];
int freq[MAXNETSIZE];
/* radpower for precomputation */
int radpower[initrad];
/* the input image itself */
unsigned char *thepicture;
} nn_quant;
/* Initialise network in range (0,0,0,0) to (255,255,255,255) and set parameters
----------------------------------------------------------------------- */
void initnet(nnq, thepic, len, sample, colours)
nn_quant *nnq;
unsigned char *thepic;
int len;
int sample;
int colours;
{
register int i;
register int *p;
/* Clear out network from previous runs */
/* thanks to Chen Bin for this fix */
memset((void*)nnq->network, 0, sizeof(nq_pixel)*MAXNETSIZE);
nnq->thepicture = thepic;
nnq->lengthcount = len;
nnq->samplefac = sample;
nnq->netsize = colours;
for (i=0; i < nnq->netsize; i++) {
p = nnq->network[i];
p[0] = p[1] = p[2] = p[3] = (i << (netbiasshift+8)) / nnq->netsize;
nnq->freq[i] = intbias / nnq->netsize; /* 1/netsize */
nnq->bias[i] = 0;
}
}
/* -------------------------- */
/* Unbias network to give byte values 0..255 and record
* position i to prepare for sort
*/
/* -------------------------- */
void unbiasnet(nn_quant *nnq)
{
int i,j,temp;
for (i=0; i < nnq->netsize; i++) {
for (j=0; j<4; j++) {
/* OLD CODE: network[i][j] >>= netbiasshift; */
/* Fix based on bug report by Juergen Weigert jw@suse.de */
temp = (nnq->network[i][j] + (1 << (netbiasshift - 1))) >> netbiasshift;
if (temp > 255) temp = 255;
nnq->network[i][j] = temp;
}
nnq->network[i][4] = i; /* record colour no */
}
}
/* Output colour map
----------------- */
void writecolourmap(nnq, f)
nn_quant *nnq;
FILE *f;
{
int i,j;
for (i=3; i>=0; i--)
for (j=0; j < nnq->netsize; j++)
putc(nnq->network[j][i], f);
}
/* Output colormap to unsigned char ptr in RGBA format */
void getcolormap(nnq, map)
nn_quant *nnq;
unsigned char *map;
{
int i,j;
for(j=0; j < nnq->netsize; j++) {
for (i=3; i>=0; i--) {
*map = nnq->network[j][i];
map++;
}
}
}
/* Insertion sort of network and building of netindex[0..255] (to do after unbias)
------------------------------------------------------------------------------- */
void inxbuild(nn_quant *nnq)
{
register int i,j,smallpos,smallval;
register int *p,*q;
int previouscol,startpos;
previouscol = 0;
startpos = 0;
for (i=0; i < nnq->netsize; i++) {
p = nnq->network[i];
smallpos = i;
smallval = p[2]; /* index on g */
/* find smallest in i..netsize-1 */
for (j=i+1; j < nnq->netsize; j++) {
q = nnq->network[j];
if (q[2] < smallval) { /* index on g */
smallpos = j;
smallval = q[2]; /* index on g */
}
}
q = nnq->network[smallpos];
/* swap p (i) and q (smallpos) entries */
if (i != smallpos) {
j = q[0];
q[0] = p[0];
p[0] = j;
j = q[1];
q[1] = p[1];
p[1] = j;
j = q[2];
q[2] = p[2];
p[2] = j;
j = q[3];
q[3] = p[3];
p[3] = j;
j = q[4];
q[4] = p[4];
p[4] = j;
}
/* smallval entry is now in position i */
if (smallval != previouscol) {
nnq->netindex[previouscol] = (startpos+i)>>1;
for (j=previouscol+1; j<smallval; j++) nnq->netindex[j] = i;
previouscol = smallval;
startpos = i;
}
}
nnq->netindex[previouscol] = (startpos+maxnetpos)>>1;
for (j=previouscol+1; j<256; j++) nnq->netindex[j] = maxnetpos; /* really 256 */
}
/* Search for ABGR values 0..255 (after net is unbiased) and return colour index
---------------------------------------------------------------------------- */
unsigned int inxsearch(nnq, al,b,g,r)
nn_quant *nnq;
register int al, b, g, r;
{
register int i, j, dist, a, bestd;
register int *p;
unsigned int best;
bestd = 1000; /* biggest possible dist is 256*3 */
best = 0;
i = nnq->netindex[g]; /* index on g */
j = i-1; /* start at netindex[g] and work outwards */
while ((i<nnq->netsize) || (j>=0)) {
if (i< nnq->netsize) {
p = nnq->network[i];
dist = p[2] - g; /* inx key */
if (dist >= bestd) i = nnq->netsize; /* stop iter */
else {
i++;
if (dist<0) dist = -dist;
a = p[1] - b;
if (a<0) a = -a;
dist += a;
if (dist<bestd) {
a = p[3] - r;
if (a<0) a = -a;
dist += a;
}
if(dist<bestd) {
a = p[0] - al;
if (a<0) a = -a;
dist += a;
}
if (dist<bestd) {
bestd=dist;
best=p[4];
}
}
}
if (j>=0) {
p = nnq->network[j];
dist = g - p[2]; /* inx key - reverse dif */
if (dist >= bestd) j = -1; /* stop iter */
else {
j--;
if (dist<0) dist = -dist;
a = p[1] - b;
if (a<0) a = -a;
dist += a;
if (dist<bestd) {
a = p[3] - r;
if (a<0) a = -a;
dist += a;
}
if(dist<bestd) {
a = p[0] - al;
if (a<0) a = -a;
dist += a;
}
if (dist<bestd) {
bestd=dist;
best=p[4];
}
}
}
}
return(best);
}
/* Search for biased ABGR values
---------------------------- */
int contest(nnq, al,b,g,r)
nn_quant *nnq;
register int al,b,g,r;
{
/* finds closest neuron (min dist) and updates freq */
/* finds best neuron (min dist-bias) and returns position */
/* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
/* bias[i] = gamma*((1/netsize)-freq[i]) */
register int i,dist,a,biasdist,betafreq;
unsigned int bestpos,bestbiaspos;
double bestd,bestbiasd;
register int *p,*f, *n;
bestd = ~(((int) 1)<<31);
bestbiasd = bestd;
bestpos = 0;
bestbiaspos = bestpos;
p = nnq->bias;
f = nnq->freq;
for (i=0; i< nnq->netsize; i++) {
n = nnq->network[i];
dist = n[0] - al;
if (dist<0) dist = -dist;
a = n[1] - b;
if (a<0) a = -a;
dist += a;
a = n[2] - g;
if (a<0) a = -a;
dist += a;
a = n[3] - r;
if (a<0) a = -a;
dist += a;
if (dist<bestd) {
bestd=dist;
bestpos=i;
}
biasdist = dist - ((*p)>>(intbiasshift-netbiasshift));
if (biasdist<bestbiasd) {
bestbiasd=biasdist;
bestbiaspos=i;
}
betafreq = (*f >> betashift);
*f++ -= betafreq;
*p++ += (betafreq<<gammashift);
}
nnq->freq[bestpos] += beta;
nnq->bias[bestpos] -= betagamma;
return(bestbiaspos);
}
/* Move neuron i towards biased (a,b,g,r) by factor alpha
---------------------------------------------------- */
void altersingle(nnq, alpha,i,al,b,g,r)
nn_quant *nnq;
register int alpha,i,al,b,g,r;
{
register int *n;
n = nnq->network[i]; /* alter hit neuron */
*n -= (alpha*(*n - al)) / initalpha;
n++;
*n -= (alpha*(*n - b)) / initalpha;
n++;
*n -= (alpha*(*n - g)) / initalpha;
n++;
*n -= (alpha*(*n - r)) / initalpha;
}
/* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
--------------------------------------------------------------------------------- */
void alterneigh(nnq, rad,i,al,b,g,r)
nn_quant *nnq;
int rad,i;
register int al,b,g,r;
{
register int j,k,lo,hi,a;
register int *p, *q;
lo = i-rad;
if (lo<-1) lo=-1;
hi = i+rad;
if (hi>nnq->netsize) hi=nnq->netsize;
j = i+1;
k = i-1;
q = nnq->radpower;
while ((j<hi) || (k>lo)) {
a = (*(++q));
if (j<hi) {
p = nnq->network[j];
*p -= (a*(*p - al)) / alpharadbias;
p++;
*p -= (a*(*p - b)) / alpharadbias;
p++;
*p -= (a*(*p - g)) / alpharadbias;
p++;
*p -= (a*(*p - r)) / alpharadbias;
j++;
}
if (k>lo) {
p = nnq->network[k];
*p -= (a*(*p - al)) / alpharadbias;
p++;
*p -= (a*(*p - b)) / alpharadbias;
p++;
*p -= (a*(*p - g)) / alpharadbias;
p++;
*p -= (a*(*p - r)) / alpharadbias;
k--;
}
}
}
/* Main Learning Loop
------------------ */
void learn(nnq, verbose) /* Stu: N.B. added parameter so that main() could control verbosity. */
nn_quant *nnq;
int verbose;
{
register int i,j,al,b,g,r;
int radius,rad,alpha,step,delta,samplepixels;
register unsigned char *p;
unsigned char *lim;
nnq->alphadec = 30 + ((nnq->samplefac-1)/3);
p = nnq->thepicture;
lim = nnq->thepicture + nnq->lengthcount;
samplepixels = nnq->lengthcount/(4 * nnq->samplefac);
/* here's a problem with small images: samplepixels < ncycles => delta = 0 */
delta = samplepixels/ncycles;
/* kludge to fix */
if(delta==0) delta = 1;
alpha = initalpha;
radius = initradius;
rad = radius >> radiusbiasshift;
for (i=0; i<rad; i++)
nnq->radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
if (verbose) gd_error_ex(GD_NOTICE, "beginning 1D learning: initial radius=%d\n", rad);
if ((nnq->lengthcount%prime1) != 0) step = 4*prime1;
else {
if ((nnq->lengthcount%prime2) !=0) step = 4*prime2;
else {
if ((nnq->lengthcount%prime3) !=0) step = 4*prime3;
else step = 4*prime4;
}
}
i = 0;
while (i < samplepixels) {
al = p[ALPHA] << netbiasshift;
b = p[BLUE] << netbiasshift;
g = p[GREEN] << netbiasshift;
r = p[RED] << netbiasshift;
j = contest(nnq, al,b,g,r);
altersingle(nnq, alpha,j,al,b,g,r);
if (rad) alterneigh(nnq, rad,j,al,b,g,r); /* alter neighbours */
p += step;
while (p >= lim) p -= nnq->lengthcount;
i++;
if (i%delta == 0) { /* FPE here if delta=0*/
alpha -= alpha / nnq->alphadec;
radius -= radius / radiusdec;
rad = radius >> radiusbiasshift;
if (rad <= 1) rad = 0;
for (j=0; j<rad; j++)
nnq->radpower[j] = alpha*(((rad*rad - j*j)*radbias)/(rad*rad));
}
}
if (verbose) gd_error_ex(GD_NOTICE, "finished 1D learning: final alpha=%f !\n",((float)alpha)/initalpha);
}
/**
* Function: gdImageNeuQuant
*
* Creates a new palette image from a truecolor image
*
* This is the same as calling <gdImageCreatePaletteFromTrueColor> with the
* quantization method <GD_QUANT_NEUQUANT>.
*
* Parameters:
* im - The image.
* max_color - The number of desired palette entries.
* sample_factor - The quantization precision between 1 (highest quality) and
* 10 (fastest).
*
* Returns:
* A newly create palette image; NULL on failure.
*/
BGD_DECLARE(gdImagePtr) gdImageNeuQuant(gdImagePtr im, const int max_color, int sample_factor)
{
const int newcolors = max_color;
const int verbose = 1;
int bot_idx, top_idx; /* for remapping of indices */
int remap[MAXNETSIZE];
int i,x;
unsigned char map[MAXNETSIZE][4];
unsigned char *d;
nn_quant *nnq = NULL;
int row;
unsigned char *rgba = NULL;
gdImagePtr dst = NULL;
/* Default it to 3 */
if (sample_factor < 1) {
sample_factor = 3;
}
/* Start neuquant */
/* Pierre:
* This implementation works with aligned contiguous buffer only
* Upcoming new buffers are contiguous and will be much faster.
* let don't bloat this code to support our good "old" 31bit format.
* It alos lets us convert palette image, if one likes to reduce
* a palette
*/
if (overflow2(gdImageSX(im), gdImageSY(im))
|| overflow2(gdImageSX(im) * gdImageSY(im), 4)) {
goto done;
}
rgba = (unsigned char *) gdMalloc(gdImageSX(im) * gdImageSY(im) * 4);
if (!rgba) {
goto done;
}
d = rgba;
for (row = 0; row < gdImageSY(im); row++) {
int *p = im->tpixels[row];
register int c;
for (i = 0; i < gdImageSX(im); i++) {
c = *p;
*d++ = gdImageAlpha(im, c);
*d++ = gdImageRed(im, c);
*d++ = gdImageBlue(im, c);
*d++ = gdImageGreen(im, c);
p++;
}
}
nnq = (nn_quant *) gdMalloc(sizeof(nn_quant));
if (!nnq) {
goto done;
}
initnet(nnq, rgba, gdImageSY(im) * gdImageSX(im) * 4, sample_factor, newcolors);
learn(nnq, verbose);
unbiasnet(nnq);
getcolormap(nnq, (unsigned char*)map);
inxbuild(nnq);
/* remapping colormap to eliminate opaque tRNS-chunk entries... */
for (top_idx = newcolors-1, bot_idx = x = 0; x < newcolors; ++x) {
if (map[x][3] == 255) { /* maxval */
remap[x] = top_idx--;
} else {
remap[x] = bot_idx++;
}
}
if (bot_idx != top_idx + 1) {
gd_error(" internal logic error: remapped bot_idx = %d, top_idx = %d\n",
bot_idx, top_idx);
goto done;
}
dst = gdImageCreate(gdImageSX(im), gdImageSY(im));
if (!dst) {
goto done;
}
for (x = 0; x < newcolors; ++x) {
dst->red[remap[x]] = map[x][0];
dst->green[remap[x]] = map[x][1];
dst->blue[remap[x]] = map[x][2];
dst->alpha[remap[x]] = map[x][3];
dst->open[remap[x]] = 0;
dst->colorsTotal++;
}
/* Do each image row */
for ( row = 0; row < gdImageSY(im); ++row ) {
int offset;
unsigned char *p = dst->pixels[row];
/* Assign the new colors */
offset = row * gdImageSX(im) * 4;
for(i=0; i < gdImageSX(im); i++) {
p[i] = remap[
inxsearch(nnq, rgba[i * 4 + offset + ALPHA],
rgba[i * 4 + offset + BLUE],
rgba[i * 4 + offset + GREEN],
rgba[i * 4 + offset + RED])
];
}
}
done:
if (rgba) {
gdFree(rgba);
}
if (nnq) {
gdFree(nnq);
}
return dst;
}

View File

@@ -0,0 +1,19 @@
/* maximum number of colours that can be used.
actual number is now passed to initcolors */
#define MAXNETSIZE 256
/* For 256 colours, fixed arrays need 8kb, plus space for the image
---------------------------------------------------------------- */
/* four primes near 500 - assume no image has a length so large */
/* that it is divisible by all four primes */
#define prime1 499
#define prime2 491
#define prime3 487
#define prime4 503
#define minpicturebytes (4*prime4) /* minimum size for input image */

1086
project/jni/gd/src/gd_png.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,364 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "gd.h"
#include "gd_intern.h"
#include <math.h>
/*
* Rotate function Added on 2003/12
* by Pierre-Alain Joye (pierre@php.net)
**/
/* Begin rotate function */
#ifdef ROTATE_PI
#undef ROTATE_PI
#endif /* ROTATE_PI */
typedef int (BGD_STDCALL *FuncPtr)(gdImagePtr, int, int);
#define ROTATE_DEG2RAD 3.1415926535897932384626433832795/180
void gdImageSkewX (gdImagePtr dst, gdImagePtr src, int uRow, int iOffset, double dWeight, int clrBack, int ignoretransparent)
{
int i, r, g, b, a, clrBackR, clrBackG, clrBackB, clrBackA;
FuncPtr f;
int pxlOldLeft, pxlLeft=0, pxlSrc;
/* Keep clrBack as color index if required */
if (src->trueColor) {
pxlOldLeft = clrBack;
f = gdImageGetTrueColorPixel;
} else {
pxlOldLeft = clrBack;
clrBackR = gdImageRed(src, clrBack);
clrBackG = gdImageGreen(src, clrBack);
clrBackB = gdImageBlue(src, clrBack);
clrBackA = gdImageAlpha(src, clrBack);
clrBack = gdTrueColorAlpha(clrBackR, clrBackG, clrBackB, clrBackA);
f = gdImageGetPixel;
}
for (i = 0; i < iOffset; i++) {
gdImageSetPixel (dst, i, uRow, clrBack);
}
if (i < dst->sx) {
gdImageSetPixel (dst, i, uRow, clrBack);
}
for (i = 0; i < src->sx; i++) {
pxlSrc = f (src,i,uRow);
r = (int)(gdImageRed(src,pxlSrc) * dWeight);
g = (int)(gdImageGreen(src,pxlSrc) * dWeight);
b = (int)(gdImageBlue(src,pxlSrc) * dWeight);
a = (int)(gdImageAlpha(src,pxlSrc) * dWeight);
if (r>255) {
r = 255;
}
if (g>255) {
g = 255;
}
if (b>255) {
b = 255;
}
if (a>127) {
a = 127;
}
pxlLeft = gdTrueColorAlpha(r, g, b, a);
r = gdImageRed(src,pxlSrc) - (r - gdImageRed(src,pxlOldLeft));
g = gdImageGreen(src,pxlSrc) - (g - gdImageGreen(src,pxlOldLeft));
b = gdImageBlue(src,pxlSrc) - (b - gdImageBlue(src,pxlOldLeft));
a = gdImageAlpha(src,pxlSrc) - (a - gdImageAlpha(src,pxlOldLeft));
if (r>255) {
r = 255;
}
if (g>255) {
g = 255;
}
if (b>255) {
b = 255;
}
if (a>127) {
a = 127;
}
if (ignoretransparent && pxlSrc == dst->transparent) {
pxlSrc = dst->transparent;
} else {
pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
if (pxlSrc == -1) {
pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
}
}
if ((i + iOffset >= 0) && (i + iOffset < dst->sx)) {
gdImageSetPixel (dst, i+iOffset, uRow, pxlSrc);
}
pxlOldLeft = pxlLeft;
}
i += iOffset;
if (i < dst->sx) {
gdImageSetPixel (dst, i, uRow, pxlLeft);
}
gdImageSetPixel (dst, iOffset, uRow, clrBack);
i--;
while (++i < dst->sx) {
gdImageSetPixel (dst, i, uRow, clrBack);
}
}
void gdImageSkewY (gdImagePtr dst, gdImagePtr src, int uCol, int iOffset, double dWeight, int clrBack, int ignoretransparent)
{
int i, iYPos=0, r, g, b, a;
FuncPtr f;
int pxlOldLeft, pxlLeft=0, pxlSrc;
if (src->trueColor) {
f = gdImageGetTrueColorPixel;
} else {
f = gdImageGetPixel;
}
for (i = 0; i<=iOffset; i++) {
gdImageSetPixel (dst, uCol, i, clrBack);
}
r = (int)((double)gdImageRed(src,clrBack) * dWeight);
g = (int)((double)gdImageGreen(src,clrBack) * dWeight);
b = (int)((double)gdImageBlue(src,clrBack) * dWeight);
a = (int)((double)gdImageAlpha(src,clrBack) * dWeight);
pxlOldLeft = gdImageColorAllocateAlpha(dst, r, g, b, a);
for (i = 0; i < src->sy; i++) {
pxlSrc = f (src, uCol, i);
iYPos = i + iOffset;
r = (int)((double)gdImageRed(src,pxlSrc) * dWeight);
g = (int)((double)gdImageGreen(src,pxlSrc) * dWeight);
b = (int)((double)gdImageBlue(src,pxlSrc) * dWeight);
a = (int)((double)gdImageAlpha(src,pxlSrc) * dWeight);
if (r>255) {
r = 255;
}
if (g>255) {
g = 255;
}
if (b>255) {
b = 255;
}
if (a>127) {
a = 127;
}
pxlLeft = gdTrueColorAlpha(r, g, b, a);
r = gdImageRed(src,pxlSrc) - (r - gdImageRed(src,pxlOldLeft));
g = gdImageGreen(src,pxlSrc) - (g - gdImageGreen(src,pxlOldLeft));
b = gdImageBlue(src,pxlSrc) - (b - gdImageBlue(src,pxlOldLeft));
a = gdImageAlpha(src,pxlSrc) - (a - gdImageAlpha(src,pxlOldLeft));
if (r>255) {
r = 255;
}
if (g>255) {
g = 255;
}
if (b>255) {
b = 255;
}
if (a>127) {
a = 127;
}
if (ignoretransparent && pxlSrc == dst->transparent) {
pxlSrc = dst->transparent;
} else {
pxlSrc = gdImageColorAllocateAlpha(dst, r, g, b, a);
if (pxlSrc == -1) {
pxlSrc = gdImageColorClosestAlpha(dst, r, g, b, a);
}
}
if ((iYPos >= 0) && (iYPos < dst->sy)) {
gdImageSetPixel (dst, uCol, iYPos, pxlSrc);
}
pxlOldLeft = pxlLeft;
}
i = iYPos;
if (i < dst->sy) {
gdImageSetPixel (dst, uCol, i, pxlLeft);
}
i--;
while (++i < dst->sy) {
gdImageSetPixel (dst, uCol, i, clrBack);
}
}
/* Rotates an image by 90 degrees (counter clockwise) */
gdImagePtr gdImageRotate90 (gdImagePtr src, int ignoretransparent)
{
int uY, uX;
int c,r,g,b,a;
gdImagePtr dst;
FuncPtr f;
if (src->trueColor) {
f = gdImageGetTrueColorPixel;
} else {
f = gdImageGetPixel;
}
dst = gdImageCreateTrueColor(src->sy, src->sx);
if (dst != NULL) {
int old_blendmode = dst->alphaBlendingFlag;
dst->alphaBlendingFlag = 0;
dst->transparent = src->transparent;
gdImagePaletteCopy (dst, src);
for (uY = 0; uY<src->sy; uY++) {
for (uX = 0; uX<src->sx; uX++) {
c = f (src, uX, uY);
if (!src->trueColor) {
r = gdImageRed(src,c);
g = gdImageGreen(src,c);
b = gdImageBlue(src,c);
a = gdImageAlpha(src,c);
c = gdTrueColorAlpha(r, g, b, a);
}
if (ignoretransparent && c == dst->transparent) {
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), dst->transparent);
} else {
gdImageSetPixel(dst, uY, (dst->sy - uX - 1), c);
}
}
}
dst->alphaBlendingFlag = old_blendmode;
}
return dst;
}
/* Rotates an image by 180 degrees (counter clockwise) */
gdImagePtr gdImageRotate180 (gdImagePtr src, int ignoretransparent)
{
int uY, uX;
int c,r,g,b,a;
gdImagePtr dst;
FuncPtr f;
if (src->trueColor) {
f = gdImageGetTrueColorPixel;
} else {
f = gdImageGetPixel;
}
dst = gdImageCreateTrueColor(src->sx, src->sy);
if (dst != NULL) {
int old_blendmode = dst->alphaBlendingFlag;
dst->alphaBlendingFlag = 0;
dst->transparent = src->transparent;
gdImagePaletteCopy (dst, src);
for (uY = 0; uY<src->sy; uY++) {
for (uX = 0; uX<src->sx; uX++) {
c = f (src, uX, uY);
if (!src->trueColor) {
r = gdImageRed(src,c);
g = gdImageGreen(src,c);
b = gdImageBlue(src,c);
a = gdImageAlpha(src,c);
c = gdTrueColorAlpha(r, g, b, a);
}
if (ignoretransparent && c == dst->transparent) {
gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), dst->transparent);
} else {
gdImageSetPixel(dst, (dst->sx - uX - 1), (dst->sy - uY - 1), c);
}
}
}
dst->alphaBlendingFlag = old_blendmode;
}
return dst;
}
/* Rotates an image by 270 degrees (counter clockwise) */
gdImagePtr gdImageRotate270 (gdImagePtr src, int ignoretransparent)
{
int uY, uX;
int c,r,g,b,a;
gdImagePtr dst;
FuncPtr f;
if (src->trueColor) {
f = gdImageGetTrueColorPixel;
} else {
f = gdImageGetPixel;
}
dst = gdImageCreateTrueColor (src->sy, src->sx);
if (dst != NULL) {
int old_blendmode = dst->alphaBlendingFlag;
dst->alphaBlendingFlag = 0;
dst->transparent = src->transparent;
gdImagePaletteCopy (dst, src);
for (uY = 0; uY<src->sy; uY++) {
for (uX = 0; uX<src->sx; uX++) {
c = f (src, uX, uY);
if (!src->trueColor) {
r = gdImageRed(src,c);
g = gdImageGreen(src,c);
b = gdImageBlue(src,c);
a = gdImageAlpha(src,c);
c = gdTrueColorAlpha(r, g, b, a);
}
if (ignoretransparent && c == dst->transparent) {
gdImageSetPixel(dst, (dst->sx - uY - 1), uX, dst->transparent);
} else {
gdImageSetPixel(dst, (dst->sx - uY - 1), uX, c);
}
}
}
dst->alphaBlendingFlag = old_blendmode;
}
return dst;
}

View File

@@ -0,0 +1,32 @@
/*
* gd_security.c
*
* Implements buffer overflow check routines.
*
* Written 2004, Phil Knirsch.
* Based on netpbm fixes by Alan Cox.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "gd.h"
#include "gd_errors.h"
int overflow2(int a, int b)
{
if(a <= 0 || b <= 0) {
gd_error_ex(GD_WARNING, "one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n");
return 1;
}
if(a > INT_MAX / b) {
gd_error_ex(GD_WARNING, "product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
return 1;
}
return 0;
}

View File

@@ -0,0 +1,62 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "gd_errors.h"
#define TRUE 1
#define FALSE 0
/* Use this for commenting out debug-print statements. */
/* Just use the first '#define' to allow all the prints... */
/*#define GD_SS_DBG(s) (s) */
#define GD_SS_DBG(s)
#ifdef HAVE_LIBPNG
/*
Function: gdImagePngToSink
*/
BGD_DECLARE(void) gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
{
gdIOCtx *out = gdNewSSCtx (NULL, outSink);
gdImagePngCtx (im, out);
out->gd_free (out);
}
/*
Function: gdImageCreateFromPngSource
See <gdImageCreateFromPng> for documentation. This is obsolete; use
<gdImageCreateFromPngCtx> instead.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromPngSource (gdSourcePtr inSource)
{
gdIOCtx *in = gdNewSSCtx (inSource, NULL);
gdImagePtr im;
im = gdImageCreateFromPngCtx (in);
in->gd_free (in);
return im;
}
#else /* no HAVE_LIBPNG */
BGD_DECLARE(void) gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
{
(void)im;
(void)outSink;
gd_error("PNG support is not available\n");
}
BGD_DECLARE(gdImagePtr) gdImageCreateFromPngSource (gdSourcePtr inSource)
{
(void)inSource;
gd_error("PNG support is not available\n");
return NULL;
}
#endif /* HAVE_LIBPNG */

359
project/jni/gd/src/gd_tga.c Normal file
View File

@@ -0,0 +1,359 @@
/**
* File: TGA Input
*
* Read TGA images.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "gd_tga.h"
#include "gd.h"
#include "gd_errors.h"
#include "gdhelpers.h"
/*
Function: gdImageCreateFromTga
Creates a gdImage from a TGA file
Parameters:
infile - Pointer to TGA binary file
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromTga(FILE *fp)
{
gdImagePtr image;
gdIOCtx* in = gdNewFileCtx(fp);
if (in == NULL) return NULL;
image = gdImageCreateFromTgaCtx(in);
in->gd_free( in );
return image;
}
/*
Function: gdImageCreateFromTgaPtr
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaPtr(int size, void *data)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0);
if (in == NULL) return NULL;
im = gdImageCreateFromTgaCtx(in);
in->gd_free(in);
return im;
}
/*
Function: gdImageCreateFromTgaCtx
Creates a gdImage from a gdIOCtx referencing a TGA binary file.
Parameters:
ctx - Pointer to a gdIOCtx structure
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaCtx(gdIOCtx* ctx)
{
int bitmap_caret = 0;
oTga *tga = NULL;
/* int pixel_block_size = 0;
int image_block_size = 0; */
volatile gdImagePtr image = NULL;
int x = 0;
int y = 0;
tga = (oTga *) gdMalloc(sizeof(oTga));
if (!tga) {
return NULL;
}
tga->bitmap = NULL;
tga->ident = NULL;
if (read_header_tga(ctx, tga) < 0) {
free_tga(tga);
return NULL;
}
/*TODO: Will this be used?
pixel_block_size = tga->bits / 8;
image_block_size = (tga->width * tga->height) * pixel_block_size;
*/
if (read_image_tga(ctx, tga) < 0) {
free_tga(tga);
return NULL;
}
image = gdImageCreateTrueColor((int)tga->width, (int)tga->height );
if (image == 0) {
free_tga( tga );
return NULL;
}
/*! \brief Populate GD image object
* Copy the pixel data from our tga bitmap buffer into the GD image
* Disable blending and save the alpha channel per default
*/
if (tga->alphabits) {
gdImageAlphaBlending(image, 0);
gdImageSaveAlpha(image, 1);
}
/* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */
for (y = 0; y < tga->height; y++) {
register int *tpix = image->tpixels[y];
for ( x = 0; x < tga->width; x++, tpix++) {
if (tga->bits == TGA_BPP_24) {
*tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]);
bitmap_caret += 3;
} else if (tga->bits == TGA_BPP_32 && tga->alphabits) {
register int a = tga->bitmap[bitmap_caret + 3];
*tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1));
bitmap_caret += 4;
}
}
}
if (tga->flipv && tga->fliph) {
gdImageFlipBoth(image);
} else if (tga->flipv) {
gdImageFlipVertical(image);
} else if (tga->fliph) {
gdImageFlipHorizontal(image);
}
free_tga(tga);
return image;
}
/*! \brief Reads a TGA header.
* Reads the header block from a binary TGA file populating the referenced TGA structure.
* \param ctx Pointer to TGA binary file
* \param tga Pointer to TGA structure
* \return int 1 on sucess, -1 on failure
*/
int read_header_tga(gdIOCtx *ctx, oTga *tga)
{
unsigned char header[18];
if (gdGetBuf(header, sizeof(header), ctx) < 18) {
gd_error("fail to read header");
return -1;
}
tga->identsize = header[0];
tga->colormaptype = header[1];
tga->imagetype = header[2];
tga->colormapstart = header[3] + (header[4] << 8);
tga->colormaplength = header[5] + (header[6] << 8);
tga->colormapbits = header[7];
tga->xstart = header[8] + (header[9] << 8);
tga->ystart = header[10] + (header[11] << 8);
tga->width = header[12] + (header[13] << 8);
tga->height = header[14] + (header[15] << 8);
tga->bits = header[16];
tga->alphabits = header[17] & 0x0f;
tga->fliph = (header[17] & 0x10) ? 1 : 0;
tga->flipv = (header[17] & 0x20) ? 0 : 1;
#if DEBUG
printf("format bps: %i\n", tga->bits);
printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv);
printf("alpha: %i\n", tga->alphabits);
printf("wxh: %i %i\n", tga->width, tga->height);
#endif
if (!((tga->bits == TGA_BPP_24 && tga->alphabits == 0)
|| (tga->bits == TGA_BPP_32 && tga->alphabits == 8)))
{
gd_error_ex(GD_WARNING, "gd-tga: %u bits per pixel with %u alpha bits not supported\n",
tga->bits, tga->alphabits);
return -1;
}
tga->ident = NULL;
if (tga->identsize > 0) {
tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char));
if(tga->ident == NULL) {
return -1;
}
gdGetBuf(tga->ident, tga->identsize, ctx);
}
return 1;
}
/*! \brief Reads a TGA image data into buffer.
* Reads the image data block from a binary TGA file populating the referenced TGA structure.
* \param ctx Pointer to TGA binary file
* \param tga Pointer to TGA structure
* \return int 0 on sucess, -1 on failure
*/
int read_image_tga( gdIOCtx *ctx, oTga *tga )
{
int pixel_block_size = (tga->bits / 8);
int image_block_size = (tga->width * tga->height) * pixel_block_size;
int* decompression_buffer = NULL;
unsigned char* conversion_buffer = NULL;
int buffer_caret = 0;
int bitmap_caret = 0;
int i = 0;
int encoded_pixels;
int rle_size;
if(overflow2(tga->width, tga->height)) {
return -1;
}
if(overflow2(tga->width * tga->height, pixel_block_size)) {
return -1;
}
if(overflow2(image_block_size, sizeof(int))) {
return -1;
}
/*! \todo Add more image type support.
*/
if (tga->imagetype != TGA_TYPE_RGB && tga->imagetype != TGA_TYPE_RGB_RLE)
return -1;
/*! \brief Allocate memmory for image block
* Allocate a chunk of memory for the image block to be passed into.
*/
tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(int));
if (tga->bitmap == NULL)
return -1;
switch (tga->imagetype) {
case TGA_TYPE_RGB:
/*! \brief Read in uncompressed RGB TGA
* Chunk load the pixel data from an uncompressed RGB type TGA.
*/
conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
if (conversion_buffer == NULL) {
return -1;
}
if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) {
gd_error("gd-tga: premature end of image data\n");
gdFree(conversion_buffer);
return -1;
}
while (buffer_caret < image_block_size) {
tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret];
buffer_caret++;
}
gdFree(conversion_buffer);
break;
case TGA_TYPE_RGB_RLE:
/*! \brief Read in RLE compressed RGB TGA
* Chunk load the pixel data from an RLE compressed RGB type TGA.
*/
decompression_buffer = (int*) gdMalloc(image_block_size * sizeof(int));
if (decompression_buffer == NULL) {
return -1;
}
conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
if (conversion_buffer == NULL) {
gd_error("gd-tga: premature end of image data\n");
gdFree( decompression_buffer );
return -1;
}
rle_size = gdGetBuf(conversion_buffer, image_block_size, ctx);
if (rle_size <= 0) {
gdFree(conversion_buffer);
gdFree(decompression_buffer);
return -1;
}
buffer_caret = 0;
while( buffer_caret < rle_size) {
decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret];
buffer_caret++;
}
buffer_caret = 0;
while( bitmap_caret < image_block_size ) {
if (buffer_caret + pixel_block_size > rle_size) {
gdFree( decompression_buffer );
gdFree( conversion_buffer );
return -1;
}
if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 );
buffer_caret++;
if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
|| buffer_caret + pixel_block_size > rle_size) {
gdFree( decompression_buffer );
gdFree( conversion_buffer );
return -1;
}
for (i = 0; i < encoded_pixels; i++) {
memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size * sizeof(int));
bitmap_caret += pixel_block_size;
}
buffer_caret += pixel_block_size;
} else {
encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
buffer_caret++;
if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
|| buffer_caret + (encoded_pixels * pixel_block_size) > rle_size) {
gdFree( decompression_buffer );
gdFree( conversion_buffer );
return -1;
}
memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size * sizeof(int));
bitmap_caret += (encoded_pixels * pixel_block_size);
buffer_caret += (encoded_pixels * pixel_block_size);
}
}
gdFree( decompression_buffer );
gdFree( conversion_buffer );
break;
}
return 1;
}
/*! \brief Cleans up a TGA structure.
* Dereferences the bitmap referenced in a TGA structure, then the structure itself
* \param tga Pointer to TGA structure
*/
void free_tga(oTga * tga)
{
if (tga) {
if (tga->ident)
gdFree(tga->ident);
if (tga->bitmap)
gdFree(tga->bitmap);
gdFree(tga);
}
}

View File

@@ -0,0 +1,52 @@
#ifndef __TGA_H
#define __TGA_H 1
#include "gd.h"
#include "gdhelpers.h"
#include "gd_intern.h"
typedef struct oTga_ {
uint8_t identsize; // size of ID field that follows 18 uint8_t header (0 usually)
uint8_t colormaptype; // type of colour map 0=none, 1=has palette [IGNORED] Adrian requested no support
uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
int colormapstart; // first colour map entry in palette [IGNORED] Adrian requested no support
int colormaplength; // number of colours in palette [IGNORED] Adrian requested no support
uint8_t colormapbits; // number of bits per palette entry 15,16,24,32 [IGNORED] Adrian requested no support
int xstart; // image x origin
int ystart; // image y origin
int width; // image width in pixels
int height; // image height in pixels
uint8_t bits; // image bits per pixel 8,16,24,32
uint8_t alphabits; // alpha bits (low 4bits of header 17)
uint8_t fliph; // horizontal or vertical
uint8_t flipv; // flip
char *ident; // identifcation tag string
int *bitmap; // bitmap data
} oTga;
#define TGA_TYPE_NO_IMAGE 0
#define TGA_TYPE_INDEXED 1
#define TGA_TYPE_RGB 2
#define TGA_TYPE_GREYSCALE 3
#define TGA_TYPE_INDEXED_RLE 9
#define TGA_TYPE_RGB_RLE 10
#define TGA_TYPE_GREYSCALE_RLE 11
#define TGA_TYPE_INDEXED_HUFFMAN_DELTA_RLE 32
#define TGA_TYPE_RGB_HUFFMAN_DELTA_QUADTREE_RLE 33
#define TGA_BPP_8 8
#define TGA_BPP_16 16
#define TGA_BPP_24 24
#define TGA_BPP_32 32
#define TGA_RLE_FLAG 128
int read_header_tga(gdIOCtx *ctx, oTga *tga);
int read_image_tga(gdIOCtx *ctx, oTga *tga);
void free_tga(oTga *tga);
#endif //__TGA_H

1073
project/jni/gd/src/gd_tiff.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
/**
* File: Transformations
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "gd.h"
/**
* Function: gdImageFlipVertical
*
* Flip an image vertically
*
* The image is mirrored upside-down.
*
* Parameters:
* im - The image.
*
* See also:
* - <gdImageFlipHorizontal>
* - <gdImageFlipBoth>
*/
BGD_DECLARE(void) gdImageFlipVertical(gdImagePtr im)
{
register int x, y;
if (im->trueColor) {
for (y = 0; y < im->sy / 2; y++) {
int *row_dst = im->tpixels[y];
int *row_src = im->tpixels[im->sy - 1 - y];
for (x = 0; x < im->sx; x++) {
register int p;
p = row_dst[x];
row_dst[x] = im->tpixels[im->sy - 1 - y][x];
row_src[x] = p;
}
}
} else {
unsigned char p;
for (y = 0; y < im->sy / 2; y++) {
for (x = 0; x < im->sx; x++) {
p = im->pixels[y][x];
im->pixels[y][x] = im->pixels[im->sy - 1 - y][x];
im->pixels[im->sy - 1 - y][x] = p;
}
}
}
return;
}
/**
* Function: gdImageFlipHorizontal
*
* Flip an image horizontally
*
* The image is mirrored left-right.
*
* Parameters:
* im - The image.
*
* See also:
* - <gdImageFlipVertical>
* - <gdImageFlipBoth>
*/
BGD_DECLARE(void) gdImageFlipHorizontal(gdImagePtr im)
{
int x, y;
if (im->trueColor) {
int *px1, *px2, tmp;
for (y = 0; y < im->sy; y++) {
px1 = im->tpixels[y];
px2 = im->tpixels[y] + im->sx - 1;
for (x = 0; x < (im->sx >> 1); x++) {
tmp = *px1;
*px1 = *px2;
*px2 = tmp;
px1++;
px2--;
}
}
} else {
unsigned char *px1, *px2, tmp;
for (y = 0; y < im->sy; y++) {
px1 = im->pixels[y];
px2 = im->pixels[y] + im->sx - 1;
for (x = 0; x < (im->sx >> 1); x++) {
tmp = *px1;
*px1 = *px2;
*px2 = tmp;
px1++;
px2--;
}
}
}
}
/**
* Function: gdImageFlipBoth
*
* Flip an image vertically and horizontally
*
* The image is mirrored upside-down and left-right.
*
* Parameters:
* im - The image.
*
* See also:
* - <gdImageFlipVertical>
* - <gdImageFlipHorizontal>
*/
BGD_DECLARE(void) gdImageFlipBoth(gdImagePtr im)
{
gdImageFlipVertical(im);
gdImageFlipHorizontal(im);
}

View File

@@ -0,0 +1,48 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include "gd.h"
/* These functions return the version information. We use functions
* so that changes in the shared library will automatically be
* reflected in executables using it without recompiling them. */
/*
Function: gdMajorVersion
*/
BGD_DECLARE(int) gdMajorVersion()
{
return GD_MAJOR_VERSION;
}
/*
Function: gdMinorVersion
*/
BGD_DECLARE(int) gdMinorVersion()
{
return GD_MINOR_VERSION;
}
/*
Function: gdReleaseVersion
*/
BGD_DECLARE(int) gdReleaseVersion()
{
return GD_RELEASE_VERSION;
}
/*
Function: gdExtraVersion
*/
BGD_DECLARE(const char *) gdExtraVersion() {
return GD_EXTRA_VERSION;
}
/*
Function: gdVersionString
*/
BGD_DECLARE(const char *) gdVersionString() {
return GD_VERSION_STRING;
}

View File

@@ -0,0 +1,278 @@
/*
* WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap
* Specification of the WBMP format can be found in the file:
* SPEC-WAESpec-19990524.pdf
* You can download the WAP specification on: http://www.wapforum.com/
*
* gd_wbmp.c
*
* Copyright (C) Johan Van den Brande (johan@vandenbrande.com)
*
* Fixed: gdImageWBMPPtr, gdImageWBMP
*
* Recoded: gdImageWBMPCtx for use with my wbmp library
* (wbmp library included, but you can find the latest distribution
* at http://www.vandenbrande.com/wbmp)
*
* Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP
*
*--------------------------------------------------------------------------
*
* Parts of this code are from Maurice Smurlo.
*
** Copyright (C) Maurice Szmurlo --- T-SIT --- January 2000
** (Maurice.Szmurlo@info.unicaen.fr)
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*
*--------------------------------------------------------------------------
*
* Parts of this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by
* Terje Sannum <terje@looplab.com>.
*
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*
*--------------------------------------------------------------------------
*
* Todo:
*
* gdCreateFromWBMP function for reading WBMP files
*
*--------------------------------------------------------------------------
*/
/**
* File: WBMP IO
*
* Read and write WBMP images.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "gd.h"
#include "gd_errors.h"
#include "gdfonts.h"
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "wbmp.h"
/* gd_putout
* ---------
* Wrapper around gdPutC for use with writewbmp
*/
void gd_putout(int i, void *out)
{
gdPutC(i, (gdIOCtx *)out);
}
/* gd_getin
* --------
* Wrapper around gdGetC for use with readwbmp
*/
int gd_getin(void *in)
{
return (gdGetC((gdIOCtx *)in));
}
/*
Function: gdImageWBMPCtx
Write the image as a wbmp file
Parameters:
image - gd image structure
fg - the index of the foreground color. any other value will be
considered as background and will not be written
out - the stream where to write
*/
BGD_DECLARE(void) gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out)
{
int x, y, pos;
Wbmp *wbmp;
/* create the WBMP */
if((wbmp = createwbmp(gdImageSX(image), gdImageSY(image), WBMP_WHITE)) == NULL) {
gd_error("Could not create WBMP\n");
return;
}
/* fill up the WBMP structure */
pos = 0;
for(y = 0; y < gdImageSY(image); y++) {
for(x = 0; x < gdImageSX(image); x++) {
if(gdImageGetPixel(image, x, y) == fg) {
wbmp->bitmap[pos] = WBMP_BLACK;
}
pos++;
}
}
/* write the WBMP to a gd file descriptor */
if(writewbmp(wbmp, &gd_putout, out)) {
gd_error("Could not save WBMP\n");
}
/* des submitted this bugfix: gdFree the memory. */
freewbmp(wbmp);
}
/*
Function: gdImageCreateFromWBMPCtx
Reads in a WBMP image via a <gdIOCtx> struct. See
<gdImageCreateFromWBMP>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPCtx(gdIOCtx *infile)
{
Wbmp *wbmp;
gdImagePtr im = NULL;
int black, white;
int col, row, pos;
if(readwbmp(&gd_getin, infile, &wbmp)) {
return (NULL);
}
if(!(im = gdImageCreate(wbmp->width, wbmp->height))) {
freewbmp(wbmp);
return NULL;
}
/* create the background color */
white = gdImageColorAllocate(im, 255, 255, 255);
/* create foreground color */
black = gdImageColorAllocate(im, 0, 0, 0);
/* fill in image (in a wbmp 1 = white/ 0 = black) */
pos = 0;
for(row = 0; row < wbmp->height; row++) {
for(col = 0; col < wbmp->width; col++) {
if(wbmp->bitmap[pos++] == WBMP_WHITE) {
gdImageSetPixel(im, col, row, white);
} else {
gdImageSetPixel(im, col, row, black);
}
}
}
freewbmp(wbmp);
return im;
}
/*
Function: gdImageCreateFromWBMP
<gdImageCreateFromWBMP> is called to load images from WBMP format
files. Invoke <gdImageCreateFromWBMP> with an already opened
pointer to a file containing the desired
image. <gdImageCreateFromWBMP> returns a gdImagePtr to the new
image, or NULL if unable to load the image (most often because the
file is corrupt or does not contain a WBMP
image). <gdImageCreateFromWBMP> does not close the file. You can
inspect the sx and sy members of the image to determine its
size. The image must eventually be destroyed using
<gdImageDestroy>.
Variants:
<gdImageCreateFromWBMPPtr> creates an image from WBMP data (i.e. the
contents of a WBMP file) already in memory.
<gdImageCreateFromWBMPCtx> reads in an image using the functions in
a <gdIOCtx> struct.
Parameters:
infile - The input FILE pointer
Returns:
A pointer to the new image or NULL if an error occurred.
Example:
(start code)
gdImagePtr im;
FILE *in;
in = fopen("mywbmp.wbmp", "rb");
im = gdImageCreateFromWBMP(in);
fclose(in);
// ... Use the image ...
gdImageDestroy(im);
(end code)
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMP(FILE *inFile)
{
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx(inFile);
if (in == NULL) return NULL;
im = gdImageCreateFromWBMPCtx(in);
in->gd_free(in);
return im;
}
/*
Function: gdImageCreateFromWBMPPtr
Parameters:
size - size of WBMP data in bytes.
data - WBMP data (i.e. contents of a WBMP file).
See <gdImageCreateFromWBMP>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromWBMPPtr(int size, void *data)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
if(!in) {
return 0;
}
im = gdImageCreateFromWBMPCtx(in);
in->gd_free(in);
return im;
}
/*
Function: gdImageWBMP
*/
BGD_DECLARE(void) gdImageWBMP(gdImagePtr im, int fg, FILE *outFile)
{
gdIOCtx *out = gdNewFileCtx(outFile);
if (out == NULL) return;
gdImageWBMPCtx(im, fg, out);
out->gd_free(out);
}
/*
Function: gdImageWBMPPtr
*/
BGD_DECLARE(void *) gdImageWBMPPtr(gdImagePtr im, int *size, int fg)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
if (out == NULL) return NULL;
gdImageWBMPCtx(im, fg, out);
rv = gdDPExtractData(out, size);
out->gd_free(out);
return rv;
}

View File

@@ -0,0 +1,363 @@
/**
* File: WebP IO
*
* Read and write WebP images.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_LIBWEBP
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "gd_errors.h"
#include "gdhelpers.h"
#include "webp/decode.h"
#include "webp/encode.h"
#define GD_WEBP_ALLOC_STEP (4*1024)
/*
Function: gdImageCreateFromWebp
<gdImageCreateFromWebp> is called to load truecolor images from
WebP format files. Invoke <gdImageCreateFromWebp> with an
already opened pointer to a file containing the desired
image. <gdImageCreateFromWebp> returns a <gdImagePtr> to the new
truecolor image, or NULL if unable to load the image (most often
because the file is corrupt or does not contain a WebP
image). <gdImageCreateFromWebp> does not close the file.
You can inspect the sx and sy members of the image to determine
its size. The image must eventually be destroyed using
<gdImageDestroy>.
*The returned image is always a truecolor image.*
Variants:
<gdImageCreateFromJpegPtr> creates an image from WebP data
already in memory.
<gdImageCreateFromJpegCtx> reads its data via the function
pointers in a <gdIOCtx> structure.
Parameters:
infile - The input FILE pointer.
Returns:
A pointer to the new *truecolor* image. This will need to be
destroyed with <gdImageDestroy> once it is no longer needed.
On error, returns NULL.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromWebp (FILE * inFile)
{
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx(inFile);
if (!in) {
return 0;
}
im = gdImageCreateFromWebpCtx(in);
in->gd_free(in);
return im;
}
/*
Function: gdImageCreateFromWebpPtr
See <gdImageCreateFromWebp>.
Parameters:
size - size of WebP data in bytes.
data - pointer to WebP data.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpPtr (int size, void *data)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
if (!in)
return 0;
im = gdImageCreateFromWebpCtx(in);
in->gd_free(in);
return im;
}
/*
Function: gdImageCreateFromWebpCtx
See <gdImageCreateFromWebp>.
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromWebpCtx (gdIOCtx * infile)
{
int width, height;
uint8_t *filedata = NULL;
uint8_t *argb = NULL;
unsigned char *read, *temp;
size_t size = 0, n;
gdImagePtr im;
int x, y;
uint8_t *p;
do {
temp = gdRealloc(filedata, size+GD_WEBP_ALLOC_STEP);
if (temp) {
filedata = temp;
read = temp + size;
} else {
if (filedata) {
gdFree(filedata);
}
gd_error("WebP decode: realloc failed");
return NULL;
}
n = gdGetBuf(read, GD_WEBP_ALLOC_STEP, infile);
if (n>0 && n!=EOF) {
size += n;
}
} while (n>0 && n!=EOF);
if (WebPGetInfo(filedata,size, &width, &height) == 0) {
gd_error("gd-webp cannot get webp info");
gdFree(temp);
return NULL;
}
im = gdImageCreateTrueColor(width, height);
if (!im) {
gdFree(temp);
return NULL;
}
argb = WebPDecodeARGB(filedata, size, &width, &height);
if (!argb) {
gd_error("gd-webp cannot allocate temporary buffer");
gdFree(temp);
gdImageDestroy(im);
return NULL;
}
for (y = 0, p = argb; y < height; y++) {
for (x = 0; x < width; x++) {
register uint8_t a = gdAlphaMax - (*(p++) >> 1);
register uint8_t r = *(p++);
register uint8_t g = *(p++);
register uint8_t b = *(p++);
im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a);
}
}
/* do not use gdFree here, in case gdFree/alloc is mapped to something else than libc */
free(argb);
gdFree(temp);
im->saveAlphaFlag = 1;
return im;
}
/* returns 0 on success, 1 on failure */
static int _gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
{
uint8_t *argb;
int x, y;
uint8_t *p;
uint8_t *out;
size_t out_size;
int ret = 0;
if (im == NULL) {
return 1;
}
if (!gdImageTrueColor(im)) {
gd_error("Palette image not supported by webp");
return 1;
}
if (quality == -1) {
quality = 80;
}
if (overflow2(gdImageSX(im), 4)) {
return 1;
}
if (overflow2(gdImageSX(im) * 4, gdImageSY(im))) {
return 1;
}
argb = (uint8_t *)gdMalloc(gdImageSX(im) * 4 * gdImageSY(im));
if (!argb) {
return 1;
}
p = argb;
for (y = 0; y < gdImageSY(im); y++) {
for (x = 0; x < gdImageSX(im); x++) {
register int c;
register char a;
c = im->tpixels[y][x];
a = gdTrueColorGetAlpha(c);
if (a == 127) {
a = 0;
} else {
a = 255 - ((a << 1) + (a >> 6));
}
*(p++) = gdTrueColorGetRed(c);
*(p++) = gdTrueColorGetGreen(c);
*(p++) = gdTrueColorGetBlue(c);
*(p++) = a;
}
}
out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quality, &out);
if (out_size == 0) {
gd_error("gd-webp encoding failed");
ret = 1;
goto freeargb;
}
gdPutBuf(out, out_size, outfile);
free(out);
freeargb:
gdFree(argb);
return ret;
}
/*
Function: gdImageWebpCtx
Write the image as WebP data via a <gdIOCtx>. See <gdImageWebpEx>
for more details.
Parameters:
im - The image to write.
outfile - The output sink.
quality - Image quality.
Returns:
Nothing.
*/
BGD_DECLARE(void) gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
{
_gdImageWebpCtx(im, outfile, quality);
}
/*
Function: gdImageWebpEx
<gdImageWebpEx> outputs the specified image to the specified file in
WebP format. The file must be open for writing. Under MSDOS and
all versions of Windows, it is important to use "wb" as opposed to
simply "w" as the mode when opening the file, and under Unix there
is no penalty for doing so. <gdImageWebpEx> does not close the file;
your code must do so.
If _quality_ is -1, a reasonable quality value (which should yield a
good general quality / size tradeoff for most situations) is used. Otherwise
_quality_ should be a value in the range 0-100, higher quality values
usually implying both higher quality and larger image sizes.
Variants:
<gdImageWebpCtx> stores the image using a <gdIOCtx> struct.
<gdImageWebpPtrEx> stores the image to RAM.
Parameters:
im - The image to save.
outFile - The FILE pointer to write to.
quality - Compression quality (0-100).
Returns:
Nothing.
*/
BGD_DECLARE(void) gdImageWebpEx (gdImagePtr im, FILE * outFile, int quality)
{
gdIOCtx *out = gdNewFileCtx(outFile);
if (out == NULL) {
return;
}
_gdImageWebpCtx(im, out, quality);
out->gd_free(out);
}
/*
Function: gdImageWebp
Variant of <gdImageWebpEx> which uses the default quality (-1).
Parameters:
im - The image to save
outFile - The FILE pointer to write to.
Returns:
Nothing.
*/
BGD_DECLARE(void) gdImageWebp (gdImagePtr im, FILE * outFile)
{
gdIOCtx *out = gdNewFileCtx(outFile);
if (out == NULL) {
return;
}
_gdImageWebpCtx(im, out, -1);
out->gd_free(out);
}
/*
Function: gdImageWebpPtr
See <gdImageWebpEx>.
*/
BGD_DECLARE(void *) gdImageWebpPtr (gdImagePtr im, int *size)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
if (out == NULL) {
return NULL;
}
if (_gdImageWebpCtx(im, out, -1)) {
rv = NULL;
} else {
rv = gdDPExtractData(out, size);
}
out->gd_free(out);
return rv;
}
/*
Function: gdImageWebpPtrEx
See <gdImageWebpEx>.
*/
BGD_DECLARE(void *) gdImageWebpPtrEx (gdImagePtr im, int *size, int quality)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
if (out == NULL) {
return NULL;
}
if (_gdImageWebpCtx(im, out, quality)) {
rv = NULL;
} else {
rv = gdDPExtractData(out, size);
}
out->gd_free(out);
return rv;
}
#endif /* HAVE_LIBWEBP */

299
project/jni/gd/src/gd_xbm.c Normal file
View File

@@ -0,0 +1,299 @@
/**
* File: XBM IO
*
* Read and write XBM images.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <ctype.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "gd.h"
#include "gd_errors.h"
#include "gdhelpers.h"
#ifdef _MSC_VER
# define strcasecmp _stricmp
#endif
#define MAX_XBM_LINE_SIZE 255
/*
Function: gdImageCreateFromXbm
<gdImageCreateFromXbm> is called to load images from X bitmap
format files. Invoke <gdImageCreateFromXbm> with an already opened
pointer to a file containing the desired
image. <gdImageCreateFromXbm> returns a <gdImagePtr> to the new
image, or NULL if unable to load the image (most often because the
file is corrupt or does not contain an X bitmap format
image). <gdImageCreateFromXbm> does not close the file.
You can inspect the sx and sy members of the image to determine
its size. The image must eventually be destroyed using
<gdImageDestroy>.
X11 X bitmaps (which define a char[]) as well as X10 X bitmaps (which define
a short[]) are supported.
Parameters:
fd - The input FILE pointer
Returns:
A pointer to the new image or NULL if an error occurred.
Example:
(start code)
gdImagePtr im;
FILE *in;
in = fopen("myxbm.xbm", "rb");
im = gdImageCreateFromXbm(in);
fclose(in);
// ... Use the image ...
gdImageDestroy(im);
(end code)
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm(FILE * fd)
{
char fline[MAX_XBM_LINE_SIZE];
char iname[MAX_XBM_LINE_SIZE];
char *type;
int value;
unsigned int width = 0, height = 0;
int fail = 0;
int max_bit = 0;
gdImagePtr im;
int bytes = 0, i;
int bit, x = 0, y = 0;
int ch;
char h[8];
unsigned int b;
rewind(fd);
while (fgets(fline, MAX_XBM_LINE_SIZE, fd)) {
fline[MAX_XBM_LINE_SIZE-1] = '\0';
if (strlen(fline) == MAX_XBM_LINE_SIZE-1) {
return 0;
}
if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
if (!(type = strrchr(iname, '_'))) {
type = iname;
} else {
type++;
}
if (!strcmp("width", type)) {
width = (unsigned int) value;
}
if (!strcmp("height", type)) {
height = (unsigned int) value;
}
} else {
if ( sscanf(fline, "static unsigned char %s = {", iname) == 1
|| sscanf(fline, "static char %s = {", iname) == 1)
{
max_bit = 128;
} else if (sscanf(fline, "static unsigned short %s = {", iname) == 1
|| sscanf(fline, "static short %s = {", iname) == 1)
{
max_bit = 32768;
}
if (max_bit) {
bytes = (width + 7) / 8 * height;
if (!bytes) {
return 0;
}
if (!(type = strrchr(iname, '_'))) {
type = iname;
} else {
type++;
}
if (!strcmp("bits[]", type)) {
break;
}
}
}
}
if (!bytes || !max_bit) {
return 0;
}
if(!(im = gdImageCreate(width, height))) {
return 0;
}
gdImageColorAllocate(im, 255, 255, 255);
gdImageColorAllocate(im, 0, 0, 0);
h[2] = '\0';
h[4] = '\0';
for (i = 0; i < bytes; i++) {
while (1) {
if ((ch=getc(fd)) == EOF) {
fail = 1;
break;
}
if (ch == 'x') {
break;
}
}
if (fail) {
break;
}
/* Get hex value */
if ((ch=getc(fd)) == EOF) {
break;
}
h[0] = ch;
if ((ch=getc(fd)) == EOF) {
break;
}
h[1] = ch;
if (max_bit == 32768) {
if ((ch=getc(fd)) == EOF) {
break;
}
h[2] = ch;
if ((ch=getc(fd)) == EOF) {
break;
}
h[3] = ch;
}
sscanf(h, "%x", &b);
for (bit = 1; bit <= max_bit; bit = bit << 1) {
gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
if (x == im->sx) {
x = 0;
y++;
if (y == im->sy) {
return im;
}
break;
}
}
}
gd_error("EOF before image was complete");
gdImageDestroy(im);
return 0;
}
/* {{{ gdCtxPrintf */
static void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
{
char buf[1024];
int len;
va_list args;
va_start(args, format);
len = vsnprintf(buf, sizeof(buf)-1, format, args);
va_end(args);
out->putBuf(out, buf, len);
}
/* }}} */
/* The compiler will optimize strlen(constant) to a constant number. */
#define gdCtxPuts(out, s) out->putBuf(out, s, strlen(s))
/**
* Function: gdImageXbmCtx
*
* Writes an image to an IO context in X11 bitmap format.
*
* Parameters:
*
* image - The <gdImagePtr> to write.
* file_name - The prefix of the XBM's identifiers. Illegal characters are
* automatically stripped.
* gd - Which color to use as forground color. All pixels with another
* color are unset.
* out - The <gdIOCtx> to write the image file to.
*
*/
BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
{
int x, y, c, b, sx, sy, p;
char *name, *f;
size_t i, l;
name = file_name;
if ((f = strrchr(name, '/')) != NULL) name = f+1;
if ((f = strrchr(name, '\\')) != NULL) name = f+1;
name = strdup(name);
if ((f = strrchr(name, '.')) != NULL && !strcasecmp(f, ".XBM")) *f = '\0';
if ((l = strlen(name)) == 0) {
free(name);
name = strdup("image");
} else {
for (i=0; i<l; i++) {
/* only in C-locale isalnum() would work */
if (!isupper(name[i]) && !islower(name[i]) && !isdigit(name[i])) {
name[i] = '_';
}
}
}
/* Since "name" comes from the user, run it through a direct puts.
* Trying to printf it into a local buffer means we'd need a large
* or dynamic buffer to hold it all. */
/* #define <name>_width 1234 */
gdCtxPuts(out, "#define ");
gdCtxPuts(out, name);
gdCtxPuts(out, "_width ");
gdCtxPrintf(out, "%d\n", gdImageSX(image));
/* #define <name>_height 1234 */
gdCtxPuts(out, "#define ");
gdCtxPuts(out, name);
gdCtxPuts(out, "_height ");
gdCtxPrintf(out, "%d\n", gdImageSY(image));
/* static unsigned char <name>_bits[] = {\n */
gdCtxPuts(out, "static unsigned char ");
gdCtxPuts(out, name);
gdCtxPuts(out, "_bits[] = {\n ");
free(name);
b = 1;
p = 0;
c = 0;
sx = gdImageSX(image);
sy = gdImageSY(image);
for (y = 0; y < sy; y++) {
for (x = 0; x < sx; x++) {
if (gdImageGetPixel(image, x, y) == fg) {
c |= b;
}
if ((b == 128) || (x == sx - 1)) {
b = 1;
if (p) {
gdCtxPuts(out, ", ");
if (!(p%12)) {
gdCtxPuts(out, "\n ");
p = 12;
}
}
p++;
gdCtxPrintf(out, "0x%02X", c);
c = 0;
} else {
b <<= 1;
}
}
}
gdCtxPuts(out, "};\n");
}

4404
project/jni/gd/src/gdfontg.c Normal file

File diff suppressed because it is too large Load Diff

4662
project/jni/gd/src/gdfontl.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3890
project/jni/gd/src/gdfonts.c Normal file

File diff suppressed because it is too large Load Diff

2613
project/jni/gd/src/gdfontt.c Normal file

File diff suppressed because it is too large Load Diff

1813
project/jni/gd/src/gdft.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gd.h"
#include "gdhelpers.h"
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
/* TBB: gd_strtok_r is not portable; provide an implementation */
#define SEP_TEST (separators[*((unsigned char *) s)])
char *
gd_strtok_r (char *s, char *sep, char **state)
{
char separators[256];
char *result = 0;
memset (separators, 0, sizeof (separators));
while (*sep) {
separators[*((unsigned char *) sep)] = 1;
sep++;
}
if (!s) {
/* Pick up where we left off */
s = *state;
}
/* 1. EOS */
if (!(*s)) {
*state = s;
return 0;
}
/* 2. Leading separators, if any */
if (SEP_TEST) {
do {
s++;
} while (SEP_TEST);
/* 2a. EOS after separators only */
if (!(*s)) {
*state = s;
return 0;
}
}
/* 3. A token */
result = s;
do {
/* 3a. Token at end of string */
if (!(*s)) {
*state = s;
return result;
}
s++;
} while (!SEP_TEST);
/* 4. Terminate token and skip trailing separators */
*s = '\0';
do {
s++;
} while (SEP_TEST);
/* 5. Return token */
*state = s;
return result;
}
void * gdCalloc (size_t nmemb, size_t size)
{
return calloc (nmemb, size);
}
void *
gdMalloc (size_t size)
{
return malloc (size);
}
void *
gdRealloc (void *ptr, size_t size)
{
return realloc (ptr, size);
}
void *
gdReallocEx (void *ptr, size_t size)
{
void *newPtr = gdRealloc (ptr, size);
if (!newPtr && ptr)
gdFree(ptr);
return newPtr;
}
/*
Function: gdFree
Frees memory that has been allocated by libgd functions.
Unless more specialized functions exists (for instance, <gdImageDestroy>),
all memory that has been allocated by public libgd functions has to be
freed by calling <gdFree>, and not by free(3), because libgd internally
doesn't use alloc(3) and friends but rather its own allocation functions,
which are, however, not publicly available.
Parameters:
ptr - Pointer to the memory space to free. If it is NULL, no operation is
performed.
Returns:
Nothing.
*/
BGD_DECLARE(void) gdFree (void *ptr)
{
free (ptr);
}

View File

@@ -0,0 +1,76 @@
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GDHELPERS_H
#define GDHELPERS_H 1
/* sys/types.h is needed for size_t on Sparc-SunOS-4.1 */
#ifndef _WIN32_WCE
#include <sys/types.h>
#else
#include <stdlib.h>
#endif /* _WIN32_WCE */
/* TBB: strtok_r is not universal; provide an implementation of it. */
char * gd_strtok_r (char *s, char *sep, char **state);
/* These functions wrap memory management. gdFree is
in gd.h, where callers can utilize it to correctly
free memory allocated by these functions with the
right version of free(). */
void *gdCalloc (size_t nmemb, size_t size);
void *gdMalloc (size_t size);
void *gdRealloc (void *ptr, size_t size);
/* The extended version of gdReallocEx will free *ptr if the
* realloc fails */
void *gdReallocEx (void *ptr, size_t size);
/* Returns nonzero if multiplying the two quantities will
result in integer overflow. Also returns nonzero if
either quantity is negative. By Phil Knirsch based on
netpbm fixes by Alan Cox. */
int overflow2(int a, int b);
/* 2.0.16: portable mutex support for thread safety. */
#if defined(CPP_SHARP)
# define gdMutexDeclare(x)
# define gdMutexSetup(x)
# define gdMutexShutdown(x)
# define gdMutexLock(x)
# define gdMutexUnlock(x)
#elif defined(_WIN32)
/* 2.0.18: must include windows.h to get CRITICAL_SECTION. */
# include <windows.h>
# define gdMutexDeclare(x) CRITICAL_SECTION x
# define gdMutexSetup(x) InitializeCriticalSection(&x)
# define gdMutexShutdown(x) DeleteCriticalSection(&x)
# define gdMutexLock(x) EnterCriticalSection(&x)
# define gdMutexUnlock(x) LeaveCriticalSection(&x)
#elif defined(HAVE_PTHREAD)
# include <pthread.h>
# define gdMutexDeclare(x) pthread_mutex_t x
# define gdMutexSetup(x) pthread_mutex_init(&x, 0)
# define gdMutexShutdown(x) pthread_mutex_destroy(&x)
# define gdMutexLock(x) pthread_mutex_lock(&x)
# define gdMutexUnlock(x) pthread_mutex_unlock(&x)
#else
# define gdMutexDeclare(x)
# define gdMutexSetup(x)
# define gdMutexShutdown(x)
# define gdMutexLock(x)
# define gdMutexUnlock(x)
#endif /* _WIN32 || HAVE_PTHREAD */
#define DPCM2DPI(dpcm) (unsigned int)((dpcm)*2.54 + 0.5)
#define DPM2DPI(dpm) (unsigned int)((dpm)*0.0254 + 0.5)
#define DPI2DPCM(dpi) (unsigned int)((dpi)/2.54 + 0.5)
#define DPI2DPM(dpi) (unsigned int)((dpi)/0.0254 + 0.5)
#endif /* GDHELPERS_H */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,726 @@
const int gdCosT[] = {
1024,
1023,
1023,
1022,
1021,
1020,
1018,
1016,
1014,
1011,
1008,
1005,
1001,
997,
993,
989,
984,
979,
973,
968,
962,
955,
949,
942,
935,
928,
920,
912,
904,
895,
886,
877,
868,
858,
848,
838,
828,
817,
806,
795,
784,
772,
760,
748,
736,
724,
711,
698,
685,
671,
658,
644,
630,
616,
601,
587,
572,
557,
542,
527,
512,
496,
480,
464,
448,
432,
416,
400,
383,
366,
350,
333,
316,
299,
282,
265,
247,
230,
212,
195,
177,
160,
142,
124,
107,
89,
71,
53,
35,
17,
0,
-17,
-35,
-53,
-71,
-89,
-107,
-124,
-142,
-160,
-177,
-195,
-212,
-230,
-247,
-265,
-282,
-299,
-316,
-333,
-350,
-366,
-383,
-400,
-416,
-432,
-448,
-464,
-480,
-496,
-512,
-527,
-542,
-557,
-572,
-587,
-601,
-616,
-630,
-644,
-658,
-671,
-685,
-698,
-711,
-724,
-736,
-748,
-760,
-772,
-784,
-795,
-806,
-817,
-828,
-838,
-848,
-858,
-868,
-877,
-886,
-895,
-904,
-912,
-920,
-928,
-935,
-942,
-949,
-955,
-962,
-968,
-973,
-979,
-984,
-989,
-993,
-997,
-1001,
-1005,
-1008,
-1011,
-1014,
-1016,
-1018,
-1020,
-1021,
-1022,
-1023,
-1023,
-1024,
-1023,
-1023,
-1022,
-1021,
-1020,
-1018,
-1016,
-1014,
-1011,
-1008,
-1005,
-1001,
-997,
-993,
-989,
-984,
-979,
-973,
-968,
-962,
-955,
-949,
-942,
-935,
-928,
-920,
-912,
-904,
-895,
-886,
-877,
-868,
-858,
-848,
-838,
-828,
-817,
-806,
-795,
-784,
-772,
-760,
-748,
-736,
-724,
-711,
-698,
-685,
-671,
-658,
-644,
-630,
-616,
-601,
-587,
-572,
-557,
-542,
-527,
-512,
-496,
-480,
-464,
-448,
-432,
-416,
-400,
-383,
-366,
-350,
-333,
-316,
-299,
-282,
-265,
-247,
-230,
-212,
-195,
-177,
-160,
-142,
-124,
-107,
-89,
-71,
-53,
-35,
-17,
0,
17,
35,
53,
71,
89,
107,
124,
142,
160,
177,
195,
212,
230,
247,
265,
282,
299,
316,
333,
350,
366,
383,
400,
416,
432,
448,
464,
480,
496,
512,
527,
542,
557,
572,
587,
601,
616,
630,
644,
658,
671,
685,
698,
711,
724,
736,
748,
760,
772,
784,
795,
806,
817,
828,
838,
848,
858,
868,
877,
886,
895,
904,
912,
920,
928,
935,
942,
949,
955,
962,
968,
973,
979,
984,
989,
993,
997,
1001,
1005,
1008,
1011,
1014,
1016,
1018,
1020,
1021,
1022,
1023,
1023
};
const int gdSinT[] = {
0,
17,
35,
53,
71,
89,
107,
124,
142,
160,
177,
195,
212,
230,
247,
265,
282,
299,
316,
333,
350,
366,
383,
400,
416,
432,
448,
464,
480,
496,
512,
527,
542,
557,
572,
587,
601,
616,
630,
644,
658,
671,
685,
698,
711,
724,
736,
748,
760,
772,
784,
795,
806,
817,
828,
838,
848,
858,
868,
877,
886,
895,
904,
912,
920,
928,
935,
942,
949,
955,
962,
968,
973,
979,
984,
989,
993,
997,
1001,
1005,
1008,
1011,
1014,
1016,
1018,
1020,
1021,
1022,
1023,
1023,
1024,
1023,
1023,
1022,
1021,
1020,
1018,
1016,
1014,
1011,
1008,
1005,
1001,
997,
993,
989,
984,
979,
973,
968,
962,
955,
949,
942,
935,
928,
920,
912,
904,
895,
886,
877,
868,
858,
848,
838,
828,
817,
806,
795,
784,
772,
760,
748,
736,
724,
711,
698,
685,
671,
658,
644,
630,
616,
601,
587,
572,
557,
542,
527,
512,
496,
480,
464,
448,
432,
416,
400,
383,
366,
350,
333,
316,
299,
282,
265,
247,
230,
212,
195,
177,
160,
142,
124,
107,
89,
71,
53,
35,
17,
0,
-17,
-35,
-53,
-71,
-89,
-107,
-124,
-142,
-160,
-177,
-195,
-212,
-230,
-247,
-265,
-282,
-299,
-316,
-333,
-350,
-366,
-383,
-400,
-416,
-432,
-448,
-464,
-480,
-496,
-512,
-527,
-542,
-557,
-572,
-587,
-601,
-616,
-630,
-644,
-658,
-671,
-685,
-698,
-711,
-724,
-736,
-748,
-760,
-772,
-784,
-795,
-806,
-817,
-828,
-838,
-848,
-858,
-868,
-877,
-886,
-895,
-904,
-912,
-920,
-928,
-935,
-942,
-949,
-955,
-962,
-968,
-973,
-979,
-984,
-989,
-993,
-997,
-1001,
-1005,
-1008,
-1011,
-1014,
-1016,
-1018,
-1020,
-1021,
-1022,
-1023,
-1023,
-1024,
-1023,
-1023,
-1022,
-1021,
-1020,
-1018,
-1016,
-1014,
-1011,
-1008,
-1005,
-1001,
-997,
-993,
-989,
-984,
-979,
-973,
-968,
-962,
-955,
-949,
-942,
-935,
-928,
-920,
-912,
-904,
-895,
-886,
-877,
-868,
-858,
-848,
-838,
-828,
-817,
-806,
-795,
-784,
-772,
-760,
-748,
-736,
-724,
-711,
-698,
-685,
-671,
-658,
-644,
-630,
-616,
-601,
-587,
-572,
-557,
-542,
-527,
-512,
-496,
-480,
-464,
-448,
-432,
-416,
-400,
-383,
-366,
-350,
-333,
-316,
-299,
-282,
-265,
-247,
-230,
-212,
-195,
-177,
-160,
-142,
-124,
-107,
-89,
-71,
-53,
-35,
-17
};

225
project/jni/gd/src/gdxpm.c Normal file
View File

@@ -0,0 +1,225 @@
/*
* Add ability to load xpm files to gd, requires the xpm
* library.
* Caolan.McNamara@ul.ie
* http://www.csn.ul.ie/~caolan
*/
/**
* File: XPM Input
*
* Read XPM images.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gd.h"
#include "gdhelpers.h"
#include "gd_color_map.h"
#include "gd_errors.h"
#ifndef HAVE_LIBXPM
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename)
{
(void)filename;
gd_error_ex(GD_ERROR, "libgd was not built with xpm support\n");
return NULL;
}
#else
#include <X11/xpm.h>
/*
Function: gdImageCreateFromXpm
<gdImageCreateFromXbm> is called to load images from XPM X Window
System color bitmap format files. This function is available only
if HAVE_XPM is selected in the Makefile and the Xpm library is
linked with the application. Unlike most gd file functions, the
Xpm functions *require filenames*, not file
pointers. <gdImageCreateFromXpm> returns a <gdImagePtr> to the new
image, or NULL if unable to load the image (most often because the
file is corrupt or does not contain an XPM bitmap format
image). You can inspect the sx and sy members of the image to
determine its size. The image must eventually be destroyed using
<gdImageDestroy>.
Parameters:
filename - The input filename (*not* FILE pointer)
Returns:
A pointer to the new image or NULL if an error occurred.
Example:
(start code)
gdImagePtr im;
FILE *in;
in = fopen("myxpm.xpm", "rb");
im = gdImageCreateFromXpm(in);
fclose(in);
// ... Use the image ...
gdImageDestroy(im);
(end code)
*/
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename)
{
XpmInfo info;
XpmImage image;
unsigned int i, j, k, number, len;
char buf[5];
gdImagePtr im = 0;
int *pointer;
int red = 0, green = 0, blue = 0;
int *colors;
int ret;
ret = XpmReadFileToXpmImage(filename, &image, &info);
if(ret != XpmSuccess) {
return 0;
}
number = image.ncolors;
if(overflow2(sizeof(int), number)) {
goto done;
}
for(i = 0; i < number; i++) {
/*
avoid NULL pointer dereference
TODO better fix need to manage monochrome/monovisual
see m_color or g4_color or g_color
*/
if (!image.colorTable[i].c_color) {
goto done;
}
}
colors = (int *)gdMalloc(sizeof(int) * number);
if(colors == NULL) {
goto done;
}
if(!(im = gdImageCreate(image.width, image.height))) {
gdFree(colors);
goto done;
}
for(i = 0; i < number; i++) {
char *c_color = image.colorTable[i].c_color;
if(strcmp(c_color, "None") == 0) {
colors[i] = gdImageGetTransparent(im);
if(colors[i] == -1) colors[i] = gdImageColorAllocate(im, 0, 0, 0);
if(colors[i] != -1) gdImageColorTransparent(im, colors[i]);
continue;
}
len = strlen(c_color);
if(len < 1) continue;
if(c_color[0] == '#') {
switch(len) {
case 4:
buf[2] = '\0';
buf[0] = buf[1] = c_color[1];
red = strtol(buf, NULL, 16);
buf[0] = buf[1] = c_color[2];
green = strtol(buf, NULL, 16);
buf[0] = buf[1] = c_color[3];
blue = strtol(buf, NULL, 16);
break;
case 7:
buf[2] = '\0';
buf[0] = c_color[1];
buf[1] = c_color[2];
red = strtol(buf, NULL, 16);
buf[0] = c_color[3];
buf[1] = c_color[4];
green = strtol(buf, NULL, 16);
buf[0] = c_color[5];
buf[1] = c_color[6];
blue = strtol(buf, NULL, 16);
break;
case 10:
buf[3] = '\0';
buf[0] = c_color[1];
buf[1] = c_color[2];
buf[2] = c_color[3];
red = strtol(buf, NULL, 16);
red /= 64;
buf[0] = c_color[4];
buf[1] = c_color[5];
buf[2] = c_color[6];
green = strtol(buf, NULL, 16);
green /= 64;
buf[0] = c_color[7];
buf[1] = c_color[8];
buf[2] = c_color[9];
blue = strtol(buf, NULL, 16);
blue /= 64;
break;
case 13:
buf[4] = '\0';
buf[0] = c_color[1];
buf[1] = c_color[2];
buf[2] = c_color[3];
buf[3] = c_color[4];
red = strtol(buf, NULL, 16);
red /= 256;
buf[0] = c_color[5];
buf[1] = c_color[6];
buf[2] = c_color[7];
buf[3] = c_color[8];
green = strtol(buf, NULL, 16);
green /= 256;
buf[0] = c_color[9];
buf[1] = c_color[10];
buf[2] = c_color[11];
buf[3] = c_color[12];
blue = strtol(buf, NULL, 16);
blue /= 256;
break;
}
} else if(!gdColorMapLookup(GD_COLOR_MAP_X11, c_color, &red, &green, &blue)) {
continue;
}
colors[i] = gdImageColorResolve(im, red, green, blue);
}
pointer = (int *)image.data;
for(i = 0; i < image.height; i++) {
for(j = 0; j < image.width; j++) {
k = *pointer++;
gdImageSetPixel(im, j, i, colors[k]);
}
}
gdFree(colors);
done:
XpmFreeXpmImage(&image);
XpmFreeXpmInfo(&info);
return im;
}
#endif /* HAVE_LIBXPM */

File diff suppressed because it is too large Load Diff

51
project/jni/gd/src/wbmp.h Normal file
View File

@@ -0,0 +1,51 @@
#ifdef __cplusplus
extern "C" {
#endif
/* WBMP
* ----
* WBMP Level 0: B/W, Uncompressed
* This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
* It does not support ExtHeaders as defined in the spec. The spec states
* that a WAP client does not need to implement ExtHeaders.
*
* (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
*
* Header file
*/
#ifndef __WBMP_H
#define __WBMP_H 1
/* WBMP struct
* -----------
* A Wireless bitmap structure
*/
typedef struct Wbmp_ {
int type; /* type of the wbmp */
int width; /* width of the image */
int height; /* height of the image */
int *bitmap;/* pointer to data: 0 = WHITE , 1 = BLACK */
}
Wbmp;
#define WBMP_WHITE 1
#define WBMP_BLACK 0
/* Proto's
* -------
*/
void putmbi(int i, void (*putout)(int c, void *out), void *out);
int getmbi(int (*getin)(void *in), void *in);
int skipheader(int (*getin)(void *in), void *in);
Wbmp *createwbmp(int width, int height, int color);
int readwbmp(int (*getin)(void *in), void *in, Wbmp **wbmp);
int writewbmp(Wbmp *wbmp, void (*putout)(int c, void *out), void *out);
void freewbmp(Wbmp *wbmp);
void printwbmp(Wbmp *wbmp);
#endif
#ifdef __cplusplus
}
#endif