Annotation of embedaddon/php/ext/gd/libgd/gd_io_dp.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    * io_dp.c
                      3:    *
                      4:    * Implements the dynamic pointer interface.
                      5:    *
                      6:    * Based on GD.pm code by Lincoln Stein for interfacing to libgd.
                      7:    * Added support for reading as well as support for 'tell' and 'seek'.
                      8:    *
                      9:    * As will all I/O modules, most functions are for local use only (called
                     10:    * via function pointers in the I/O context).
                     11:    *
                     12:    * gdDPExtractData is the exception to this: it will return the pointer to
                     13:    * the internal data, and reset the internal storage.
                     14:    *
                     15:    * Written/Modified 1999, Philip Warner.
                     16:    *
                     17:  */
                     18: 
                     19: #include <math.h>
                     20: #include <string.h>
                     21: #include <stdlib.h>
                     22: #include "gd.h"
                     23: #include "gdhelpers.h"
                     24: 
                     25: #define TRUE 1
                     26: #define FALSE 0
                     27: 
                     28: /* this is used for creating images in main memory */
                     29: typedef struct dpStruct
                     30: {
                     31:        void *data;
                     32:        int logicalSize;
                     33:        int realSize;
                     34:        int dataGood;
                     35:        int pos;
                     36:        int freeOK;
                     37: } dynamicPtr;
                     38: 
                     39: typedef struct dpIOCtx
                     40: {
                     41:        gdIOCtx ctx;
                     42:        dynamicPtr *dp;
                     43: } dpIOCtx;
                     44: 
                     45: typedef struct dpIOCtx *dpIOCtxPtr;
                     46: 
                     47: /* these functions operate on in-memory dynamic pointers */
                     48: static int allocDynamic (dynamicPtr * dp, int initialSize, void *data);
                     49: static int appendDynamic (dynamicPtr * dp, const void *src, int size);
                     50: static int gdReallocDynamic (dynamicPtr * dp, int required);
                     51: static int trimDynamic (dynamicPtr * dp);
                     52: static void gdFreeDynamicCtx (struct gdIOCtx *ctx);
                     53: static dynamicPtr *newDynamic (int initialSize, void *data, int freeOKFlag);
                     54: 
                     55: static int dynamicPutbuf (struct gdIOCtx *, const void *, int);
                     56: static void dynamicPutchar (struct gdIOCtx *, int a);
                     57: 
                     58: static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len);
                     59: static int dynamicGetchar (gdIOCtxPtr ctx);
                     60: 
                     61: static int dynamicSeek (struct gdIOCtx *, const int);
                     62: static long dynamicTell (struct gdIOCtx *);
                     63: 
                     64: /* return data as a dynamic pointer */
                     65: gdIOCtx * gdNewDynamicCtx (int initialSize, void *data)
                     66: {
                     67:        return gdNewDynamicCtxEx(initialSize, data, 1);
                     68: }
                     69: 
                     70: gdIOCtx * gdNewDynamicCtxEx (int initialSize, void *data, int freeOKFlag)
                     71: {
                     72:        dpIOCtx *ctx;
                     73:        dynamicPtr *dp;
                     74: 
                     75:        ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx));
                     76: 
                     77:        dp = newDynamic(initialSize, data, freeOKFlag);
                     78: 
                     79:        ctx->dp = dp;
                     80: 
                     81:        ctx->ctx.getC = dynamicGetchar;
                     82:        ctx->ctx.putC = dynamicPutchar;
                     83: 
                     84:        ctx->ctx.getBuf = dynamicGetbuf;
                     85:        ctx->ctx.putBuf = dynamicPutbuf;
                     86: 
                     87:        ctx->ctx.seek = dynamicSeek;
                     88:        ctx->ctx.tell = dynamicTell;
                     89: 
                     90:        ctx->ctx.gd_free = gdFreeDynamicCtx;
                     91: 
                     92:        return (gdIOCtx *) ctx;
                     93: }
                     94: 
                     95: void * gdDPExtractData (struct gdIOCtx *ctx, int *size)
                     96: {
                     97:        dynamicPtr *dp;
                     98:        dpIOCtx *dctx;
                     99:        void *data;
                    100: 
                    101:        dctx = (dpIOCtx *) ctx;
                    102:        dp = dctx->dp;
                    103: 
                    104:        /* clean up the data block and return it */
                    105:        if (dp->dataGood) {
                    106:                trimDynamic (dp);
                    107:                *size = dp->logicalSize;
                    108:                data = dp->data;
                    109:        } else {
                    110:                *size = 0;
                    111:                data = NULL;
                    112:                if (dp->data != NULL && dp->freeOK) {
                    113:                        gdFree(dp->data);
                    114:                }
                    115:        }
                    116: 
                    117:        dp->data = NULL;
                    118:        dp->realSize = 0;
                    119:        dp->logicalSize = 0;
                    120: 
                    121:        return data;
                    122: }
                    123: 
                    124: static void gdFreeDynamicCtx (struct gdIOCtx *ctx)
                    125: {
                    126:        dynamicPtr *dp;
                    127:        dpIOCtx *dctx;
                    128: 
                    129:        dctx = (dpIOCtx *) ctx;
                    130:        dp = dctx->dp;
                    131: 
                    132:        gdFree(ctx);
                    133: 
                    134:        dp->realSize = 0;
                    135:        dp->logicalSize = 0;
                    136: 
                    137:        gdFree(dp);
                    138: }
                    139: 
                    140: static long dynamicTell (struct gdIOCtx *ctx)
                    141: {
                    142:        dpIOCtx *dctx;
                    143: 
                    144:        dctx = (dpIOCtx *) ctx;
                    145: 
                    146:        return (dctx->dp->pos);
                    147: }
                    148: 
                    149: static int dynamicSeek (struct gdIOCtx *ctx, const int pos)
                    150: {
                    151:        int bytesNeeded;
                    152:        dynamicPtr *dp;
                    153:        dpIOCtx *dctx;
                    154: 
                    155:        dctx = (dpIOCtx *) ctx;
                    156:        dp = dctx->dp;
                    157: 
                    158:        if (!dp->dataGood) {
                    159:                return FALSE;
                    160:        }
                    161: 
                    162:        bytesNeeded = pos;
                    163:        if (bytesNeeded > dp->realSize) {
                    164:                /* 2.0.21 */
                    165:                if (!dp->freeOK) {
                    166:                        return FALSE;
                    167:                }
                    168:                gdReallocDynamic (dp, dp->realSize * 2);
                    169:        }
                    170: 
                    171:        /* if we get here, we can be sure that we have enough bytes to copy safely */
                    172: 
                    173:        /* Extend the logical size if we seek beyond EOF. */
                    174:        if (pos > dp->logicalSize) {
                    175:                dp->logicalSize = pos;
                    176:        }
                    177: 
                    178:        dp->pos = pos;
                    179: 
                    180:        return TRUE;
                    181: }
                    182: 
                    183: /* return data as a dynamic pointer */
                    184: static dynamicPtr * newDynamic (int initialSize, void *data, int freeOKFlag)
                    185: {
                    186:        dynamicPtr *dp;
                    187:        dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
                    188: 
                    189:        allocDynamic (dp, initialSize, data);
                    190: 
                    191:        dp->pos = 0;
                    192:        dp->freeOK = freeOKFlag;
                    193: 
                    194:        return dp;
                    195: }
                    196: 
                    197: static int
                    198: dynamicPutbuf (struct gdIOCtx *ctx, const void *buf, int size)
                    199: {
                    200:   dpIOCtx *dctx;
                    201:   dctx = (dpIOCtx *) ctx;
                    202: 
                    203:   appendDynamic (dctx->dp, buf, size);
                    204: 
                    205:   if (dctx->dp->dataGood)
                    206:     {
                    207:       return size;
                    208:     }
                    209:   else
                    210:     {
                    211:       return -1;
                    212:     };
                    213: 
                    214: }
                    215: 
                    216: static void dynamicPutchar (struct gdIOCtx *ctx, int a)
                    217: {
                    218:        unsigned char b;
                    219:        dpIOCtxPtr dctx;
                    220: 
                    221:        b = a;
                    222:        dctx = (dpIOCtxPtr) ctx;
                    223: 
                    224:        appendDynamic(dctx->dp, &b, 1);
                    225: }
                    226: 
                    227: static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
                    228: {
                    229:        int rlen, remain;
                    230:        dpIOCtxPtr dctx;
                    231:        dynamicPtr *dp;
                    232: 
                    233:        dctx = (dpIOCtxPtr) ctx;
                    234:        dp = dctx->dp;
                    235: 
                    236:        remain = dp->logicalSize - dp->pos;
                    237:        if (remain >= len) {
                    238:                rlen = len;
                    239:        } else {
                    240:                if (remain == 0) {
                    241:                        return EOF;
                    242:                }
                    243:                rlen = remain;
                    244:        }
                    245: 
                    246:        memcpy(buf, (void *) ((char *) dp->data + dp->pos), rlen);
                    247:        dp->pos += rlen;
                    248: 
                    249:        return rlen;
                    250: }
                    251: 
                    252: static int dynamicGetchar (gdIOCtxPtr ctx)
                    253: {
                    254:        unsigned char b;
                    255:        int rv;
                    256: 
                    257:        rv = dynamicGetbuf (ctx, &b, 1);
                    258:        if (rv != 1) {
                    259:                return EOF;
                    260:        } else {
                    261:                return b;               /* (b & 0xff); */
                    262:        }
                    263: }
                    264: 
                    265: /* *********************************************************************
                    266: 
                    267:  * InitDynamic - Return a dynamically resizable void*
                    268:  *
                    269:  * *********************************************************************
                    270:  */
                    271: static int
                    272: allocDynamic (dynamicPtr * dp, int initialSize, void *data)
                    273: {
                    274: 
                    275:        if (data == NULL) {
                    276:                dp->logicalSize = 0;
                    277:                dp->dataGood = FALSE;
                    278:                dp->data = gdMalloc(initialSize);
                    279:        } else {
                    280:                dp->logicalSize = initialSize;
                    281:                dp->dataGood = TRUE;
                    282:                dp->data = data;
                    283:        }
                    284: 
                    285:        dp->realSize = initialSize;
                    286:        dp->dataGood = TRUE;
                    287:        dp->pos = 0;
                    288: 
                    289:        return TRUE;
                    290: }
                    291: 
                    292: /* append bytes to the end of a dynamic pointer */
                    293: static int appendDynamic (dynamicPtr * dp, const void *src, int size)
                    294: {
                    295:        int bytesNeeded;
                    296:        char *tmp;
                    297: 
                    298:        if (!dp->dataGood) {
                    299:                return FALSE;
                    300:        }
                    301: 
                    302:        /*  bytesNeeded = dp->logicalSize + size; */
                    303:        bytesNeeded = dp->pos + size;
                    304: 
                    305:        if (bytesNeeded > dp->realSize) {
                    306:                /* 2.0.21 */
                    307:                if (!dp->freeOK) {
                    308:                        return FALSE;
                    309:                }
                    310:                gdReallocDynamic(dp, bytesNeeded * 2);
                    311:        }
                    312: 
                    313:        /* if we get here, we can be sure that we have enough bytes to copy safely */
                    314:        /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
                    315: 
                    316:        tmp = (char *) dp->data;
                    317:        memcpy((void *) (tmp + (dp->pos)), src, size);
                    318:        dp->pos += size;
                    319: 
                    320:        if (dp->pos > dp->logicalSize) {
                    321:                dp->logicalSize = dp->pos;
                    322:        }
                    323: 
                    324:        return TRUE;
                    325: }
                    326: 
                    327: /* grow (or shrink) dynamic pointer */
                    328: static int gdReallocDynamic (dynamicPtr * dp, int required)
                    329: {
                    330:        void *newPtr;
                    331: 
                    332:        /* First try gdRealloc(). If that doesn't work, make a new memory block and copy. */
                    333:        if ((newPtr = gdRealloc(dp->data, required))) {
                    334:                dp->realSize = required;
                    335:                dp->data = newPtr;
                    336:                return TRUE;
                    337:        }
                    338: 
                    339:        /* create a new pointer */
                    340:        newPtr = gdMalloc(required);
                    341: 
                    342:        /* copy the old data into it */
                    343:        memcpy(newPtr, dp->data, dp->logicalSize);
                    344:        gdFree(dp->data);
                    345:        dp->data = newPtr;
                    346: 
                    347:        dp->realSize = required;
                    348: 
                    349:        return TRUE;
                    350: }
                    351: 
                    352: /* trim pointer so that its real and logical sizes match */
                    353: static int trimDynamic (dynamicPtr * dp)
                    354: {
                    355:        /* 2.0.21: we don't reallocate memory we don't own */
                    356:        if (!dp->freeOK) {
                    357:                return FALSE;
                    358:        }
                    359:        return gdReallocDynamic(dp, dp->logicalSize);
                    360: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>