Annotation of embedaddon/php/ext/gd/libgd/gd_io_dp.c, revision 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>