static l_int32 gifWriteFunc(GifFileType *gif, const GifByteType *src, l_int32 bytesToWrite) { L_BBUFFER *buffer; PROCNAME("gifWriteFunc"); if ((buffer = (L_BBUFFER*)gif->UserData) == NULL) return ERROR_INT("UserData not set", procName, -1); if(bbufferRead(buffer, (l_uint8*)src, bytesToWrite) == 0) return bytesToWrite; return 0; }
/*! * zlibUncompress() * * Input: datain (byte buffer with compressed input data) * nin (number of bytes of input data) * &nout (<return> number of bytes of output data) * Return: dataout (uncompressed data), or null on error * * Notes: * (1) See zlibCompress(). */ l_uint8 * zlibUncompress(l_uint8 *datain, size_t nin, size_t *pnout) { l_uint8 *dataout; l_uint8 *bufferin, *bufferout; l_int32 status; size_t nbytes; BBUFFER *bbin, *bbout; z_stream z; PROCNAME("zlibUncompress"); if (!datain) return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL); if ((bufferin = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL) return (l_uint8 *)ERROR_PTR("bufferin not made", procName, NULL); if ((bufferout = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL) return (l_uint8 *)ERROR_PTR("bufferout not made", procName, NULL); if ((bbin = bbufferCreate(datain, nin)) == NULL) return (l_uint8 *)ERROR_PTR("bbin not made", procName, NULL); if ((bbout = bbufferCreate(NULL, 0)) == NULL) return (l_uint8 *)ERROR_PTR("bbout not made", procName, NULL); z.zalloc = (alloc_func)0; z.zfree = (free_func)0; z.next_in = bufferin; z.avail_in = 0; z.next_out = bufferout; z.avail_out = L_BUF_SIZE; inflateInit(&z); for ( ; ; ) { if (z.avail_in == 0) { z.next_in = bufferin; bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes); /* fprintf(stderr, " wrote %d bytes to bufferin\n", nbytes); */ z.avail_in = nbytes; } if (z.avail_in == 0) break; status = inflate(&z, Z_SYNC_FLUSH); /* fprintf(stderr, " status is %d, bytesleft = %d, totalout = %d\n", status, z.avail_out, z.total_out); */ nbytes = L_BUF_SIZE - z.avail_out; if (nbytes) { bbufferRead(bbout, bufferout, nbytes); /* fprintf(stderr, " read %d bytes from bufferout\n", nbytes); */ } z.next_out = bufferout; z.avail_out = L_BUF_SIZE; } inflateEnd(&z); bbufferDestroy(&bbin); dataout = bbufferDestroyAndSaveData(&bbout, pnout); FREE(bufferin); FREE(bufferout); return dataout; }
/*! * zlibCompress() * * Input: datain (byte buffer with input data) * nin (number of bytes of input data) * &nout (<return> number of bytes of output data) * Return: dataout (compressed data), or null on error * * Notes: * (1) We repeatedly read in and fill up an input buffer, * compress the data, and read it back out. zlib * uses two byte buffers internally in the z_stream * data structure. We use the bbuffers to feed data * into the fixed bufferin, and feed it out of bufferout, * in the same way that a pair of streams would normally * be used if the data were being read from one file * and written to another. This is done iteratively, * compressing L_BUF_SIZE bytes of input data at a time. */ l_uint8 * zlibCompress(l_uint8 *datain, size_t nin, size_t *pnout) { l_uint8 *dataout; l_int32 status; l_int32 flush; size_t nbytes; l_uint8 *bufferin, *bufferout; BBUFFER *bbin, *bbout; z_stream z; PROCNAME("zlibCompress"); if (!datain) return (l_uint8 *)ERROR_PTR("datain not defined", procName, NULL); /* Set up fixed size buffers used in z_stream */ if ((bufferin = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL) return (l_uint8 *)ERROR_PTR("bufferin not made", procName, NULL); if ((bufferout = (l_uint8 *)CALLOC(L_BUF_SIZE, sizeof(l_uint8))) == NULL) return (l_uint8 *)ERROR_PTR("bufferout not made", procName, NULL); /* Set up bbuffers and load bbin with the data */ if ((bbin = bbufferCreate(datain, nin)) == NULL) return (l_uint8 *)ERROR_PTR("bbin not made", procName, NULL); if ((bbout = bbufferCreate(NULL, 0)) == NULL) return (l_uint8 *)ERROR_PTR("bbout not made", procName, NULL); z.zalloc = (alloc_func)0; z.zfree = (free_func)0; z.opaque = (voidpf)0; z.next_in = bufferin; z.avail_in = 0; z.next_out = bufferout; z.avail_out = L_BUF_SIZE; status = deflateInit(&z, ZLIB_COMPRESSION_LEVEL); if (status != Z_OK) return (l_uint8 *)ERROR_PTR("deflateInit failed", procName, NULL); do { if (z.avail_in == 0) { z.next_in = bufferin; bbufferWrite(bbin, bufferin, L_BUF_SIZE, &nbytes); #if DEBUG fprintf(stderr, " wrote %d bytes to bufferin\n", nbytes); #endif /* DEBUG */ z.avail_in = nbytes; } flush = (bbin->n) ? Z_SYNC_FLUSH : Z_FINISH; status = deflate(&z, flush); #if DEBUG fprintf(stderr, " status is %d, bytesleft = %d, totalout = %d\n", status, z.avail_out, z.total_out); #endif /* DEBUG */ nbytes = L_BUF_SIZE - z.avail_out; if (nbytes) { bbufferRead(bbout, bufferout, nbytes); #if DEBUG fprintf(stderr, " read %d bytes from bufferout\n", nbytes); #endif /* DEBUG */ } z.next_out = bufferout; z.avail_out = L_BUF_SIZE; } while (flush != Z_FINISH); deflateEnd(&z); bbufferDestroy(&bbin); dataout = bbufferDestroyAndSaveData(&bbout, pnout); FREE(bufferin); FREE(bufferout); return dataout; }
main(int argc, char **argv) { char *filein, *fileout; l_uint8 *array1, *array2, *dataout, *dataout2; l_int32 i, blocksize; size_t nbytes, nout, nout2; BBUFFER *bb, *bb2; FILE *fp; static char mainName[] = "buffertest"; if (argc != 3) exit(ERROR_INT(" Syntax: buffertest filein fileout", mainName, 1)); filein = argv[1]; fileout = argv[2]; if ((array1 = l_binaryRead(filein, &nbytes)) == NULL) exit(ERROR_INT("array not made", mainName, 1)); fprintf(stderr, " Bytes read from file: %ld\n", nbytes); /* Application of byte buffer ops: compress/decompress in memory */ #if 1 dataout = zlibCompress(array1, nbytes, &nout); l_binaryWrite(fileout, "w", dataout, nout); dataout2 = zlibUncompress(dataout, nout, &nout2); l_binaryWrite("/tmp/junktest", "w", dataout2, nout2); fprintf(stderr, "nbytes in = %ld, nbytes comp = %ld, nbytes uncomp = %ld\n", nbytes, nout, nout2); lept_free(dataout); lept_free(dataout2); #endif /* Low-level byte buffer read/write test */ #if 0 bb = bbufferCreate(array1, nbytes); bbufferRead(bb, array1, nbytes); array2 = (l_uint8 *)lept_calloc(2 * nbytes, sizeof(l_uint8)); fprintf(stderr, " Bytes initially in buffer: %d\n", bb->n); blocksize = (2 * nbytes) / NBLOCKS; for (i = 0; i <= NBLOCKS; i++) { bbufferWrite(bb, array2, blocksize, &nout); fprintf(stderr, " block %d: wrote %d bytes\n", i + 1, nout); } fprintf(stderr, " Bytes left in buffer: %d\n", bb->n); bb2 = bbufferCreate(NULL, 0); bbufferRead(bb2, array1, nbytes); fp = lept_fopen(fileout, "wb"); bbufferWriteStream(bb2, fp, nbytes, &nout); fprintf(stderr, " bytes written out to fileout: %d\n", nout); bbufferDestroy(&bb); bbufferDestroy(&bb2); lept_free(array2); #endif lept_free(array1); return 0; }