diff --git a/backend/bmp.c b/backend/bmp.c index 7baaea5a..31aa8499 100644 --- a/backend/bmp.c +++ b/backend/bmp.c @@ -36,10 +36,10 @@ #include "common.h" #include "bmp.h" /* Bitmap header structure */ #include -#ifdef _MSC_VER -#include -#include -#endif +#ifdef _MSC_VER +#include +#include +#endif #define SSET "0123456789ABCDEF" @@ -50,8 +50,8 @@ int bmp_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width unsigned int data_size; unsigned char *bitmap_file_start, *bmp_posn; FILE *bmp_file; - bitmap_file_header_t file_header; - bitmap_info_header_t info_header; + bitmap_file_header_t file_header; + bitmap_info_header_t info_header; switch (rotate_angle) { case 0: @@ -236,5 +236,6 @@ int bmp_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width fwrite(bitmap_file_start, file_header.file_size, 1, bmp_file); fclose(bmp_file); + free(bitmap_file_start); return 0; } \ No newline at end of file diff --git a/backend/gif.c b/backend/gif.c index 8c7c5908..ab55cad9 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -35,286 +35,286 @@ #include #include "common.h" #include "pcx.h" /* PCX header structure */ -#include -#ifdef _MSC_VER -#include -#include +#include +#ifdef _MSC_VER +#include +#include #endif #define SSET "0123456789ABCDEF" - -/* Index of transparent color, -1 for no transparent color - * This might be set into a variable if transparency is activated as an option - */ -#define TRANSPARENT_INDEX (-1) - -/* Used bit depth, may be changed for bigger pallet in future */ -#define DESTINATION_IMAGE_BITS 1 -#include - -typedef struct s_statestruct { - unsigned char * pOut; - unsigned char *pIn; - unsigned int InLen; - unsigned int OutLength; - unsigned int OutPosCur; - unsigned int OutByteCountPos; - unsigned short ClearCode; - unsigned short FreeCode; - char fByteCountByteSet; - unsigned char OutBitsFree; - unsigned short NodeAxon[4096]; - unsigned short NodeNext[4096]; - unsigned char NodePix[4096]; -} statestruct; - -static char BufferNextByte(statestruct *pState) -{ - (pState->OutPosCur)++; - /* Check if this position is a byte count position - * fg_f_bytecountbyte_set indicates, if byte count position bytes should be - * inserted in general. - * If this is true, and the distance to the last byte count position is 256 - * (e.g. 255 bytes in between), a byte count byte is inserted, and the value - * of the last one is set to 255. - * */ - if ( pState->fByteCountByteSet && ( pState->OutByteCountPos + 256 == pState->OutPosCur ) ) - { - (pState->pOut)[pState->OutByteCountPos] = 255; - pState->OutByteCountPos = pState->OutPosCur; - (pState->OutPosCur)++; - } - if ( pState->OutPosCur >= pState->OutLength ) - return 1; - (pState->pOut)[pState->OutPosCur]=0x00; - return 0; -} - -static char AddCodeToBuffer(statestruct *pState, unsigned short CodeIn,unsigned char CodeBits) -{ - /* Check, if we may fill up the current byte completely */ - if (CodeBits >= pState->OutBitsFree) - { - (pState->pOut)[pState->OutPosCur] |= (unsigned char) - ( CodeIn << ( 8 - pState->OutBitsFree ) ); - if ( BufferNextByte(pState) ) - return -1; - CodeIn = (unsigned short) ( CodeIn >> pState->OutBitsFree ); - CodeBits -= pState->OutBitsFree; - pState->OutBitsFree = 8; - /* Write a full byte if there are at least 8 code bits left */ - if (CodeBits >= pState->OutBitsFree) - { - (pState->pOut)[pState->OutPosCur] = (unsigned char) CodeIn; - if ( BufferNextByte(pState) ) - return -1; - CodeIn = (unsigned short) ( CodeIn >> 8 ); - CodeBits -= 8; - } - } - /* The remaining bits of CodeIn fit in the current byte. */ - if( CodeBits > 0 ) - { - (pState->pOut)[pState->OutPosCur] |= (unsigned char) - ( CodeIn << ( 8 - pState->OutBitsFree ) ); - pState->OutBitsFree -= CodeBits; - } - return 0; -} - -static void FlushStringTable(statestruct *pState) -{ - unsigned short Pos; - for( Pos = 0; Pos < pState->ClearCode; Pos++ ) - { - (pState->NodeAxon)[Pos] = 0; - } -} - - -unsigned short FindPixelOutlet( statestruct *pState, unsigned short HeadNode, unsigned char Byte ) -{ - unsigned short Outlet; - - Outlet = (pState->NodeAxon)[HeadNode]; - while( Outlet ) - { - if ( (pState->NodePix)[Outlet] == Byte ) - return Outlet; - Outlet = (pState->NodeNext)[Outlet]; - } - return 0; -} - -static char NextCode ( statestruct *pState, unsigned char * pPixelValueCur, unsigned char CodeBits ) -{ - unsigned short UpNode; - unsigned short DownNode; - /* start with the root node for last pixel chain */ - UpNode = *pPixelValueCur; - if ( (pState->InLen) == 0 ) - return AddCodeToBuffer(pState, UpNode, CodeBits ); - - *pPixelValueCur = (*(pState->pIn))-'0'; - (pState->pIn)++; - (pState->InLen)--; - /* Follow the string table and the data stream to the end of the longest string that has a code */ - while( 0 != ( DownNode = FindPixelOutlet(pState, UpNode, *pPixelValueCur ) ) ) - { - UpNode = DownNode; - if ( (pState->InLen) == 0 ) - return AddCodeToBuffer(pState, UpNode, CodeBits); - - *pPixelValueCur = (*(pState->pIn)) - '0'; - (pState->pIn)++; - (pState->InLen)--; - } - /* Submit 'UpNode' which is the code of the longest string */ - if ( AddCodeToBuffer(pState, UpNode, CodeBits ) ) - return -1; - /* ... and extend the string by appending 'PixelValueCur' */ - /* Create a successor node for 'PixelValueCur' whose code is 'freecode' */ - (pState->NodePix)[pState->FreeCode] = *pPixelValueCur; - (pState->NodeAxon)[pState->FreeCode] = (pState->NodeNext)[pState->FreeCode]=0; - /* ...and link it to the end of the chain emanating from fg_axon[UpNode]. */ - DownNode = (pState->NodeAxon)[UpNode]; - if( ! DownNode ) - { - (pState->NodeAxon)[UpNode] = pState->FreeCode; - } else { - while( (pState->NodeNext)[DownNode] ) - { - DownNode = (pState->NodeNext)[DownNode]; - } - (pState->NodeNext)[DownNode] = pState->FreeCode; - } - return 1; -} - -int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int InLen) -{ - unsigned char PixelValueCur; - unsigned char CodeBits; - unsigned short Pos; - statestruct State; - - State.pIn = pIn; - State.InLen = InLen; - State.pOut = pOut; - State.OutLength = OutLength; - // > Get first data byte - if (State.InLen == 0) - return 0; - - PixelValueCur = (unsigned char) ((*(State.pIn)) - '0'); - (State.pIn)++; - (State.InLen)--; - CodeBits = 3; - State.ClearCode = 4; - State.FreeCode = 6; - State.OutBitsFree = 8; - State.OutPosCur = -1; - State.fByteCountByteSet = 0; - - if ( BufferNextByte(&State) ) - return 0; - - for ( Pos = 0; Pos < State.ClearCode; Pos++) - State.NodePix[Pos] = (unsigned char) Pos; - - FlushStringTable(&State); - - /* Write what the GIF specification calls the "code size". */ - (State.pOut)[State.OutPosCur] = 2; - /* Reserve first bytecount byte */ - if ( BufferNextByte(&State) ) - return 0; - State.OutByteCountPos = State.OutPosCur; - if ( BufferNextByte(&State) ) - return 0; - State.fByteCountByteSet = 1; - /* Submit one 'ClearCode' as the first code */ - if ( AddCodeToBuffer(&State, State.ClearCode, CodeBits) ) - return 0; - - for(;;) - { - char Res; - /* generate and save the next code, which may consist of multiple input pixels. */ - Res = NextCode(&State, &PixelValueCur, CodeBits); - if ( Res < 0) - return 0; - //* Check for end of data stream */ - if( ! Res ) - { - /* submit 'eoi' as the last item of the code stream */ - if ( AddCodeToBuffer(&State, (unsigned short)(State.ClearCode + 1), CodeBits ) ) - return 0; - State.fByteCountByteSet = 0; - if( State.OutBitsFree < 8 ) - { - if ( BufferNextByte(&State) ) - return 0; - } - // > Update last bytecount byte; - if ( State.OutByteCountPos < State.OutPosCur ) - { - (State.pOut)[State.OutByteCountPos] = (unsigned char) (State.OutPosCur - State.OutByteCountPos - 1); - } - State.OutPosCur++; - return State.OutPosCur; - } - /* Check for currently last code */ - if( State.FreeCode == ( 1U << CodeBits ) ) - CodeBits++; - State.FreeCode++; - /* Check for full stringtable */ - if( State.FreeCode == 0xfff ) - { - FlushStringTable(&State); - if ( AddCodeToBuffer(&State, State.ClearCode, CodeBits ) ) - return 0; - - CodeBits=(unsigned char)( 1 + 2 ); - State.FreeCode=(unsigned short)( State.ClearCode + 2 ); - } - } -} - -int gif_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) { + +/* Index of transparent color, -1 for no transparent color + * This might be set into a variable if transparency is activated as an option + */ +#define TRANSPARENT_INDEX (-1) + +/* Used bit depth, may be changed for bigger pallet in future */ +#define DESTINATION_IMAGE_BITS 1 +#include + +typedef struct s_statestruct { + unsigned char * pOut; + unsigned char *pIn; + unsigned int InLen; + unsigned int OutLength; + unsigned int OutPosCur; + unsigned int OutByteCountPos; + unsigned short ClearCode; + unsigned short FreeCode; + char fByteCountByteSet; + unsigned char OutBitsFree; + unsigned short NodeAxon[4096]; + unsigned short NodeNext[4096]; + unsigned char NodePix[4096]; +} statestruct; + +static char BufferNextByte(statestruct *pState) +{ + (pState->OutPosCur)++; + /* Check if this position is a byte count position + * fg_f_bytecountbyte_set indicates, if byte count position bytes should be + * inserted in general. + * If this is true, and the distance to the last byte count position is 256 + * (e.g. 255 bytes in between), a byte count byte is inserted, and the value + * of the last one is set to 255. + * */ + if ( pState->fByteCountByteSet && ( pState->OutByteCountPos + 256 == pState->OutPosCur ) ) + { + (pState->pOut)[pState->OutByteCountPos] = 255; + pState->OutByteCountPos = pState->OutPosCur; + (pState->OutPosCur)++; + } + if ( pState->OutPosCur >= pState->OutLength ) + return 1; + (pState->pOut)[pState->OutPosCur]=0x00; + return 0; +} + +static char AddCodeToBuffer(statestruct *pState, unsigned short CodeIn,unsigned char CodeBits) +{ + /* Check, if we may fill up the current byte completely */ + if (CodeBits >= pState->OutBitsFree) + { + (pState->pOut)[pState->OutPosCur] |= (unsigned char) + ( CodeIn << ( 8 - pState->OutBitsFree ) ); + if ( BufferNextByte(pState) ) + return -1; + CodeIn = (unsigned short) ( CodeIn >> pState->OutBitsFree ); + CodeBits -= pState->OutBitsFree; + pState->OutBitsFree = 8; + /* Write a full byte if there are at least 8 code bits left */ + if (CodeBits >= pState->OutBitsFree) + { + (pState->pOut)[pState->OutPosCur] = (unsigned char) CodeIn; + if ( BufferNextByte(pState) ) + return -1; + CodeIn = (unsigned short) ( CodeIn >> 8 ); + CodeBits -= 8; + } + } + /* The remaining bits of CodeIn fit in the current byte. */ + if( CodeBits > 0 ) + { + (pState->pOut)[pState->OutPosCur] |= (unsigned char) + ( CodeIn << ( 8 - pState->OutBitsFree ) ); + pState->OutBitsFree -= CodeBits; + } + return 0; +} + +static void FlushStringTable(statestruct *pState) +{ + unsigned short Pos; + for( Pos = 0; Pos < pState->ClearCode; Pos++ ) + { + (pState->NodeAxon)[Pos] = 0; + } +} + + +unsigned short FindPixelOutlet( statestruct *pState, unsigned short HeadNode, unsigned char Byte ) +{ + unsigned short Outlet; + + Outlet = (pState->NodeAxon)[HeadNode]; + while( Outlet ) + { + if ( (pState->NodePix)[Outlet] == Byte ) + return Outlet; + Outlet = (pState->NodeNext)[Outlet]; + } + return 0; +} + +static char NextCode ( statestruct *pState, unsigned char * pPixelValueCur, unsigned char CodeBits ) +{ + unsigned short UpNode; + unsigned short DownNode; + /* start with the root node for last pixel chain */ + UpNode = *pPixelValueCur; + if ( (pState->InLen) == 0 ) + return AddCodeToBuffer(pState, UpNode, CodeBits ); + + *pPixelValueCur = (*(pState->pIn))-'0'; + (pState->pIn)++; + (pState->InLen)--; + /* Follow the string table and the data stream to the end of the longest string that has a code */ + while( 0 != ( DownNode = FindPixelOutlet(pState, UpNode, *pPixelValueCur ) ) ) + { + UpNode = DownNode; + if ( (pState->InLen) == 0 ) + return AddCodeToBuffer(pState, UpNode, CodeBits); + + *pPixelValueCur = (*(pState->pIn)) - '0'; + (pState->pIn)++; + (pState->InLen)--; + } + /* Submit 'UpNode' which is the code of the longest string */ + if ( AddCodeToBuffer(pState, UpNode, CodeBits ) ) + return -1; + /* ... and extend the string by appending 'PixelValueCur' */ + /* Create a successor node for 'PixelValueCur' whose code is 'freecode' */ + (pState->NodePix)[pState->FreeCode] = *pPixelValueCur; + (pState->NodeAxon)[pState->FreeCode] = (pState->NodeNext)[pState->FreeCode]=0; + /* ...and link it to the end of the chain emanating from fg_axon[UpNode]. */ + DownNode = (pState->NodeAxon)[UpNode]; + if( ! DownNode ) + { + (pState->NodeAxon)[UpNode] = pState->FreeCode; + } else { + while( (pState->NodeNext)[DownNode] ) + { + DownNode = (pState->NodeNext)[DownNode]; + } + (pState->NodeNext)[DownNode] = pState->FreeCode; + } + return 1; +} + +int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int InLen) +{ + unsigned char PixelValueCur; + unsigned char CodeBits; + unsigned short Pos; + statestruct State; + + State.pIn = pIn; + State.InLen = InLen; + State.pOut = pOut; + State.OutLength = OutLength; + // > Get first data byte + if (State.InLen == 0) + return 0; + + PixelValueCur = (unsigned char) ((*(State.pIn)) - '0'); + (State.pIn)++; + (State.InLen)--; + CodeBits = 3; + State.ClearCode = 4; + State.FreeCode = 6; + State.OutBitsFree = 8; + State.OutPosCur = -1; + State.fByteCountByteSet = 0; + + if ( BufferNextByte(&State) ) + return 0; + + for ( Pos = 0; Pos < State.ClearCode; Pos++) + State.NodePix[Pos] = (unsigned char) Pos; + + FlushStringTable(&State); + + /* Write what the GIF specification calls the "code size". */ + (State.pOut)[State.OutPosCur] = 2; + /* Reserve first bytecount byte */ + if ( BufferNextByte(&State) ) + return 0; + State.OutByteCountPos = State.OutPosCur; + if ( BufferNextByte(&State) ) + return 0; + State.fByteCountByteSet = 1; + /* Submit one 'ClearCode' as the first code */ + if ( AddCodeToBuffer(&State, State.ClearCode, CodeBits) ) + return 0; + + for(;;) + { + char Res; + /* generate and save the next code, which may consist of multiple input pixels. */ + Res = NextCode(&State, &PixelValueCur, CodeBits); + if ( Res < 0) + return 0; + //* Check for end of data stream */ + if( ! Res ) + { + /* submit 'eoi' as the last item of the code stream */ + if ( AddCodeToBuffer(&State, (unsigned short)(State.ClearCode + 1), CodeBits ) ) + return 0; + State.fByteCountByteSet = 0; + if( State.OutBitsFree < 8 ) + { + if ( BufferNextByte(&State) ) + return 0; + } + // > Update last bytecount byte; + if ( State.OutByteCountPos < State.OutPosCur ) + { + (State.pOut)[State.OutByteCountPos] = (unsigned char) (State.OutPosCur - State.OutByteCountPos - 1); + } + State.OutPosCur++; + return State.OutPosCur; + } + /* Check for currently last code */ + if( State.FreeCode == ( 1U << CodeBits ) ) + CodeBits++; + State.FreeCode++; + /* Check for full stringtable */ + if( State.FreeCode == 0xfff ) + { + FlushStringTable(&State); + if ( AddCodeToBuffer(&State, State.ClearCode, CodeBits ) ) + return 0; + + CodeBits=(unsigned char)( 1 + 2 ); + State.FreeCode=(unsigned short)( State.ClearCode + 2 ); + } + } +} + +int gif_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle) { char outbuf[10]; int errno; int row, column; FILE *gif_file; - unsigned short ImageWidth; - unsigned short ImageHeight; - unsigned short usTemp; - int byte_out; -#ifdef _MSC_VER - char* rotated_bitmap; - char * lzwoutbuf; -#endif + unsigned short ImageWidth; + unsigned short ImageHeight; + unsigned short usTemp; + int byte_out; +#ifdef _MSC_VER + char* rotated_bitmap; + char * lzwoutbuf; +#endif #ifndef _MSC_VER char rotated_bitmap[image_height * image_width]; - char lzwoutbuf[image_height * image_width]; + char lzwoutbuf[image_height * image_width]; #else - rotated_bitmap = (char *) _alloca((image_height * image_width) * sizeof(char)); + rotated_bitmap = (char *) _alloca((image_height * image_width) * sizeof(char)); lzwoutbuf = (char *) _alloca((image_height * image_width) * sizeof(char)); #endif /* _MSC_VER */ switch (rotate_angle) { case 0: - case 180: - ImageWidth = image_width; + case 180: + ImageWidth = image_width; ImageHeight = image_height; symbol->bitmap_width = image_width; symbol->bitmap_height = image_height; break; case 90: case 270: - ImageWidth = image_height; - ImageHeight = image_width; + ImageWidth = image_height; + ImageHeight = image_width; symbol->bitmap_width = image_height; symbol->bitmap_height = image_width; break; @@ -395,114 +395,115 @@ int gif_pixel_plot(struct zint_symbol *symbol, int image_height, int image_width strcpy(symbol->errtxt, "Can't open output file"); return ZINT_ERROR_FILE_ACCESS; } - } - /*ImageWidth = 2; - ImageHeight = 2; + } + /*ImageWidth = 2; + ImageHeight = 2; rotated_bitmap[0] = 1; - rotated_bitmap[1] = 1; - rotated_bitmap[2] = 0; - rotated_bitmap[3] = 0; - */ - - /* GIF signature (6) */ - memcpy(outbuf,"GIF87a",6); - if ( TRANSPARENT_INDEX != -1 ) - outbuf[4]='9'; - fwrite(outbuf, 6, 1, gif_file); - /* Screen Descriptor (7) */ - /* Screen Width */ - usTemp=(unsigned short)ImageWidth; - outbuf[0] = (unsigned char)(0xff & usTemp); - outbuf[1] = (unsigned char)( (0xff00 & usTemp) / 0x100 ); - /* Screen Height */ - usTemp=(unsigned short)ImageHeight; - outbuf[2] = (unsigned char)( 0xff & usTemp ); - outbuf[3] = (unsigned char)( (0xff00 & usTemp) / 0x100 ); - /* write ImageBits-1 to the three least significant bits of byte 5 of - * the Screen Descriptor - */ - outbuf[4] = (unsigned char)( 0xf0 | (0x7&(DESTINATION_IMAGE_BITS-1)) ); - /* Background color = colortable index 0 */ - outbuf[5] = 0x00; - /* Byte 7 must be 0x00 */ - outbuf[6] = 0x00; - fwrite(outbuf, 7, 1, gif_file); - /* Global Color Table (6) */ - /* RGB 0 color */ - outbuf[0] = (unsigned char)(16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); - outbuf[1] = (unsigned char)(16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); - outbuf[2] = (unsigned char)(16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); - /* RGB 1 color */ - outbuf[3] = (unsigned char)(16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); - outbuf[4] = (unsigned char)(16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); - outbuf[5] = (unsigned char)(16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); - fwrite(outbuf, 6, 1, gif_file); - - /* Graphic control extension (8) */ - /* A graphic control extension block is used for overlay gifs. - * This is necessary to define a transparent color. - */ - if (TRANSPARENT_INDEX != -1) - { - /* Extension Introducer = '!' */ - outbuf[0] = '\x21'; - /* Graphic Control Label */ - outbuf[1] = '\xf9'; - /* Block Size */ - outbuf[2] = 4; - /* Packet fields: - * 3 Reserved - * 3 Disposal Method: 0 No Action, 1 No Dispose, 2: Background, 3: Prev. - * 1 User Input Flag: 0: no user input, 1: user input - * 1 Transparent Color Flag: 0: No Transparency, 1: Transparency index - */ - outbuf[3] = 1; - /* Delay Time */ - outbuf[4] = 0; - outbuf[5] = 0; - /* Transparent Color Index */ - outbuf[6] = (unsigned char)TRANSPARENT_INDEX; - /* Block Terminator */ - outbuf[7] = 0; - fwrite(outbuf, 8, 1, gif_file); - } - /* Image Descriptor */ - /* Image separator character = ',' */ - outbuf[0] = 0x2c; - /* "Image Left" */ - outbuf[1] = 0x00; - outbuf[2] = 0x00; - /* "Image Top" */ - outbuf[3] = 0x00; - outbuf[4] = 0x00; - /* Image Width (low byte first) */ - outbuf[5] = (unsigned char)(0xff & ImageWidth); - outbuf[6] = (unsigned char)((0xff00 & ImageWidth) / 0x100); - /* Image Height */ - outbuf[7] = (unsigned char)(0xff & ImageHeight); - outbuf[8] = (unsigned char)((0xff00 & ImageHeight) / 0x100); - - /* Byte 10 contains the interlaced flag and - * information on the local color table. - * There is no local color table if its most significant bit is reset. - */ - outbuf[9] = (unsigned char)(0|(0x7 & (DESTINATION_IMAGE_BITS-1))); - fwrite(outbuf, 10, 1, gif_file); - - /* call lzw encoding */ - byte_out = gif_lzw( - (unsigned char *) lzwoutbuf, - image_height * image_width, - (unsigned char *) rotated_bitmap, - image_height * image_width); - if (byte_out <= 0) - { - return ZINT_ERROR_MEMORY; - } - fwrite(lzwoutbuf, byte_out, 1, gif_file); + rotated_bitmap[1] = 1; + rotated_bitmap[2] = 0; + rotated_bitmap[3] = 0; + */ + + /* GIF signature (6) */ + memcpy(outbuf,"GIF87a",6); + if ( TRANSPARENT_INDEX != -1 ) + outbuf[4]='9'; + fwrite(outbuf, 6, 1, gif_file); + /* Screen Descriptor (7) */ + /* Screen Width */ + usTemp=(unsigned short)ImageWidth; + outbuf[0] = (unsigned char)(0xff & usTemp); + outbuf[1] = (unsigned char)( (0xff00 & usTemp) / 0x100 ); + /* Screen Height */ + usTemp=(unsigned short)ImageHeight; + outbuf[2] = (unsigned char)( 0xff & usTemp ); + outbuf[3] = (unsigned char)( (0xff00 & usTemp) / 0x100 ); + /* write ImageBits-1 to the three least significant bits of byte 5 of + * the Screen Descriptor + */ + outbuf[4] = (unsigned char)( 0xf0 | (0x7&(DESTINATION_IMAGE_BITS-1)) ); + /* Background color = colortable index 0 */ + outbuf[5] = 0x00; + /* Byte 7 must be 0x00 */ + outbuf[6] = 0x00; + fwrite(outbuf, 7, 1, gif_file); + /* Global Color Table (6) */ + /* RGB 0 color */ + outbuf[0] = (unsigned char)(16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]); + outbuf[1] = (unsigned char)(16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]); + outbuf[2] = (unsigned char)(16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]); + /* RGB 1 color */ + outbuf[3] = (unsigned char)(16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]); + outbuf[4] = (unsigned char)(16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]); + outbuf[5] = (unsigned char)(16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]); + fwrite(outbuf, 6, 1, gif_file); + + /* Graphic control extension (8) */ + /* A graphic control extension block is used for overlay gifs. + * This is necessary to define a transparent color. + */ + if (TRANSPARENT_INDEX != -1) + { + /* Extension Introducer = '!' */ + outbuf[0] = '\x21'; + /* Graphic Control Label */ + outbuf[1] = '\xf9'; + /* Block Size */ + outbuf[2] = 4; + /* Packet fields: + * 3 Reserved + * 3 Disposal Method: 0 No Action, 1 No Dispose, 2: Background, 3: Prev. + * 1 User Input Flag: 0: no user input, 1: user input + * 1 Transparent Color Flag: 0: No Transparency, 1: Transparency index + */ + outbuf[3] = 1; + /* Delay Time */ + outbuf[4] = 0; + outbuf[5] = 0; + /* Transparent Color Index */ + outbuf[6] = (unsigned char)TRANSPARENT_INDEX; + /* Block Terminator */ + outbuf[7] = 0; + fwrite(outbuf, 8, 1, gif_file); + } + /* Image Descriptor */ + /* Image separator character = ',' */ + outbuf[0] = 0x2c; + /* "Image Left" */ + outbuf[1] = 0x00; + outbuf[2] = 0x00; + /* "Image Top" */ + outbuf[3] = 0x00; + outbuf[4] = 0x00; + /* Image Width (low byte first) */ + outbuf[5] = (unsigned char)(0xff & ImageWidth); + outbuf[6] = (unsigned char)((0xff00 & ImageWidth) / 0x100); + /* Image Height */ + outbuf[7] = (unsigned char)(0xff & ImageHeight); + outbuf[8] = (unsigned char)((0xff00 & ImageHeight) / 0x100); - /* GIF terminator */ - fputc('\x3b', gif_file); + /* Byte 10 contains the interlaced flag and + * information on the local color table. + * There is no local color table if its most significant bit is reset. + */ + outbuf[9] = (unsigned char)(0|(0x7 & (DESTINATION_IMAGE_BITS-1))); + fwrite(outbuf, 10, 1, gif_file); + + /* call lzw encoding */ + byte_out = gif_lzw( + (unsigned char *) lzwoutbuf, + image_height * image_width, + (unsigned char *) rotated_bitmap, + image_height * image_width); + if (byte_out <= 0) + { + fclose(gif_file); + return ZINT_ERROR_MEMORY; + } + fwrite(lzwoutbuf, byte_out, 1, gif_file); + + /* GIF terminator */ + fputc('\x3b', gif_file); fclose(gif_file); return 0; diff --git a/backend/library.c b/backend/library.c index a5a1826d..bebd9cff 100644 --- a/backend/library.c +++ b/backend/library.c @@ -105,6 +105,8 @@ void ZBarcode_Delete(struct zint_symbol *symbol) { if (symbol->rendered != NULL) { struct zint_render_line *line, *l; struct zint_render_string *string, *s; + struct zint_render_ring *ring, *r; + struct zint_render_hexagon *hexagon, *h; // Free lines line = symbol->rendered->lines; @@ -121,6 +123,22 @@ void ZBarcode_Delete(struct zint_symbol *symbol) { free(s->text); free(s); } + + // Free Rings + ring = symbol->rendered->rings; + while (ring) { + r = ring; + ring = ring->next; + free(r); + } + + // Free Hexagons + hexagon = symbol->rendered->hexagons; + while (hexagon) { + h = hexagon; + hexagon = hexagon->next; + free(h); + } // Free Render free(symbol->rendered); diff --git a/backend/ps.c b/backend/ps.c index cea08a48..c04db70e 100644 --- a/backend/ps.c +++ b/backend/ps.c @@ -115,20 +115,24 @@ int ps_plot(struct zint_symbol *symbol) { if (strlen(symbol->fgcolour) != 6) { strcpy(symbol->errtxt, "Malformed foreground colour target"); + fclose(feps); return ZINT_ERROR_INVALID_OPTION; } if (strlen(symbol->bgcolour) != 6) { strcpy(symbol->errtxt, "Malformed background colour target"); + fclose(feps); return ZINT_ERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed foreground colour target"); + fclose(feps); return ZINT_ERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed background colour target"); + fclose(feps); return ZINT_ERROR_INVALID_OPTION; } locale = setlocale(LC_ALL, "C"); diff --git a/backend/raster.c b/backend/raster.c index a5c5719b..2b259a0a 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -341,6 +341,7 @@ int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_ /* Apply scale options by creating another pixel buffer */ if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { printf("Insufficient memory for pixel buffer"); + free(pixelbuf); return ZINT_ERROR_ENCODING_PROBLEM; } else { for (i = 0; i < (scale_width * scale_height); i++) { @@ -902,6 +903,7 @@ int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_t /* Apply scale options by creating another pixel buffer */ if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) { + free(pixelbuf); printf("Insufficient memory for pixel buffer"); return ZINT_ERROR_ENCODING_PROBLEM; } else { diff --git a/backend/svg.c b/backend/svg.c index 64576eb2..081d7406 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -111,20 +111,24 @@ int svg_plot(struct zint_symbol *symbol) { if (strlen(symbol->fgcolour) != 6) { strcpy(symbol->errtxt, "Malformed foreground colour target"); + fclose(fsvg); return ZINT_ERROR_INVALID_OPTION; } if (strlen(symbol->bgcolour) != 6) { strcpy(symbol->errtxt, "Malformed background colour target"); + fclose(fsvg); return ZINT_ERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*) symbol->fgcolour, strlen(symbol->fgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed foreground colour target"); + fclose(fsvg); return ZINT_ERROR_INVALID_OPTION; } error_number = is_sane(SSET, (unsigned char*) symbol->bgcolour, strlen(symbol->bgcolour)); if (error_number == ZINT_ERROR_INVALID_DATA) { strcpy(symbol->errtxt, "Malformed background colour target"); + fclose(fsvg); return ZINT_ERROR_INVALID_OPTION; } locale = setlocale(LC_ALL, "C");