mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Add 10 colours plus transparency ("T") to gif export.
This commit is contained in:
parent
d20c6b6b78
commit
327d6ec88b
@ -47,10 +47,10 @@
|
||||
/* 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)
|
||||
#define TRANSPARENT_INDEX (15)
|
||||
|
||||
/* Used bit depth, may be changed for bigger pallet in future */
|
||||
#define DESTINATION_IMAGE_BITS 1
|
||||
/* Used bit depth: 10 value pallet is 4 bit */
|
||||
#define DESTINATION_IMAGE_BITS 4
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct s_statestruct {
|
||||
@ -69,6 +69,30 @@ typedef struct s_statestruct {
|
||||
unsigned char NodePix[4096];
|
||||
} statestruct;
|
||||
|
||||
/* Transform a Pixel to a lzw colourmap index.
|
||||
* See the 16 entries colour map definition in the code at the end for the mapping
|
||||
*/
|
||||
static unsigned char PixelToCode(unsigned char PixelValue)
|
||||
{
|
||||
|
||||
switch (PixelValue)
|
||||
{
|
||||
case '0': return 0; /* standard background */
|
||||
case '1': return 1; /* standard foreground */
|
||||
case 'W': return 2; /* white */
|
||||
case 'C': return 3; /* cyan */
|
||||
case 'B': return 4; /* blue */
|
||||
case 'M': return 5; /* magenta */
|
||||
case 'R': return 6; /* red */
|
||||
case 'Y': return 7; /* yellow */
|
||||
case 'G': return 8; /* green */
|
||||
case 'K': return 9; /* black */
|
||||
case 'T': return 15; /* transparent */
|
||||
default: return 15; /* error case - return */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char BufferNextByte(statestruct *pState) {
|
||||
(pState->OutPosCur)++;
|
||||
/* Check if this position is a byte count position
|
||||
@ -144,7 +168,7 @@ static char NextCode(statestruct *pState, unsigned char * pPixelValueCur, unsign
|
||||
if ((pState->InLen) == 0)
|
||||
return AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
|
||||
*pPixelValueCur = (*(pState->pIn)) - '0';
|
||||
*pPixelValueCur = PixelToCode(*(pState->pIn));
|
||||
(pState->pIn)++;
|
||||
(pState->InLen)--;
|
||||
/* Follow the string table and the data stream to the end of the longest string that has a code */
|
||||
@ -153,7 +177,7 @@ static char NextCode(statestruct *pState, unsigned char * pPixelValueCur, unsign
|
||||
if ((pState->InLen) == 0)
|
||||
return AddCodeToBuffer(pState, UpNode, CodeBits);
|
||||
|
||||
*pPixelValueCur = (*(pState->pIn)) - '0';
|
||||
*pPixelValueCur = PixelToCode(*(pState->pIn));
|
||||
(pState->pIn)++;
|
||||
(pState->InLen)--;
|
||||
}
|
||||
@ -191,12 +215,12 @@ static int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int I
|
||||
if (State.InLen == 0)
|
||||
return 0;
|
||||
|
||||
PixelValueCur = (unsigned char) ((*(State.pIn)) - '0');
|
||||
PixelValueCur = PixelToCode(*(State.pIn));
|
||||
(State.pIn)++;
|
||||
(State.InLen)--;
|
||||
CodeBits = 3;
|
||||
State.ClearCode = 4;
|
||||
State.FreeCode = 6;
|
||||
CodeBits = DESTINATION_IMAGE_BITS+1;
|
||||
State.ClearCode = (1 << DESTINATION_IMAGE_BITS);
|
||||
State.FreeCode = State.ClearCode+2;
|
||||
State.OutBitsFree = 8;
|
||||
State.OutPosCur = -1;
|
||||
State.fByteCountByteSet = 0;
|
||||
@ -210,7 +234,7 @@ static int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int I
|
||||
FlushStringTable(&State);
|
||||
|
||||
/* Write what the GIF specification calls the "code size". */
|
||||
(State.pOut)[State.OutPosCur] = 2;
|
||||
(State.pOut)[State.OutPosCur] = DESTINATION_IMAGE_BITS;
|
||||
/* Reserve first bytecount byte */
|
||||
if (BufferNextByte(&State))
|
||||
return 0;
|
||||
@ -255,14 +279,14 @@ static int gif_lzw(unsigned char *pOut, int OutLength, unsigned char *pIn, int I
|
||||
if (AddCodeToBuffer(&State, State.ClearCode, CodeBits))
|
||||
return 0;
|
||||
|
||||
CodeBits = (unsigned char) (1 + 2);
|
||||
CodeBits = (unsigned char) (1 + DESTINATION_IMAGE_BITS);
|
||||
State.FreeCode = (unsigned short) (State.ClearCode + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
char outbuf[10];
|
||||
unsigned char outbuf[10];
|
||||
FILE *gif_file;
|
||||
unsigned short usTemp;
|
||||
int byte_out;
|
||||
@ -315,6 +339,11 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
outbuf[3] = (unsigned char) ((0xff00 & usTemp) / 0x100);
|
||||
/* write ImageBits-1 to the three least significant bits of byte 5 of
|
||||
* the Screen Descriptor
|
||||
* Bits 76543210
|
||||
* 1 : Global colour map
|
||||
* 111 : 8 bit colour depth of the palette
|
||||
* 0 : Not ordered in decreasing importance
|
||||
* 011 : 4 bit palette
|
||||
*/
|
||||
outbuf[4] = (unsigned char) (0xf0 | (0x7 & (DESTINATION_IMAGE_BITS - 1)));
|
||||
/* Background color = colortable index 0 */
|
||||
@ -322,16 +351,49 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
/* Byte 7 must be 0x00 */
|
||||
outbuf[6] = 0x00;
|
||||
fwrite(outbuf, 7, 1, gif_file);
|
||||
/* Global Color Table (6) */
|
||||
/* RGB 0 color */
|
||||
/* Global Color Table (16*3) */
|
||||
/* Colour index 0: 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 */
|
||||
/* Colour index 1: 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);
|
||||
/* Colour index 2: "W" for White color */
|
||||
outbuf[6] = 255; outbuf[7] = 255; outbuf[8] = 255;
|
||||
fwrite(outbuf, 9, 1, gif_file);
|
||||
/* Colour index 3: "C" for Cyan colour */
|
||||
outbuf[0] = 0; outbuf[1] = 255; outbuf[2] = 255;
|
||||
/* Colour index 4: "B" for Blue colour */
|
||||
outbuf[3] = 0; outbuf[4] = 0; outbuf[5] = 255;
|
||||
/* Colour index 5: "M" for Magenta colour */
|
||||
outbuf[6] = 255; outbuf[7] = 0; outbuf[8] = 255;
|
||||
fwrite(outbuf, 9, 1, gif_file);
|
||||
/* Colour index 6: "R" for red colour */
|
||||
outbuf[0] = 255; outbuf[1] = 0; outbuf[2] = 0;
|
||||
/* Colour index 7: "Y" for yellow colour */
|
||||
outbuf[3] = 255; outbuf[4] = 255; outbuf[5] = 0;
|
||||
/* Colour index 8: "G" for green colour */
|
||||
outbuf[6] = 0; outbuf[7] = 255; outbuf[8] = 0;
|
||||
fwrite(outbuf, 9, 1, gif_file);
|
||||
/* Colour index 9: "K" for black colour */
|
||||
outbuf[0] = 0; outbuf[1] = 0; outbuf[2] = 0;
|
||||
/* Colour index 10: unused, set to black colour*/
|
||||
outbuf[3] = 0; outbuf[4] = 0; outbuf[5] = 0;
|
||||
/* Colour index 11: unused, set to black colour */
|
||||
outbuf[6] = 0; outbuf[7] = 0; outbuf[8] = 0;
|
||||
fwrite(outbuf, 9, 1, gif_file);
|
||||
/* Colour index 12: unused, set to black colour */
|
||||
outbuf[0] = 0; outbuf[1] = 0; outbuf[2] = 0;
|
||||
/* Colour index 13: unused, set to black colour*/
|
||||
outbuf[3] = 0; outbuf[4] = 0; outbuf[5] = 0;
|
||||
/* Colour index 14: unused, set to black colour */
|
||||
outbuf[6] = 0; outbuf[7] = 0; outbuf[8] = 0;
|
||||
fwrite(outbuf, 9, 1, gif_file);
|
||||
/* Colour index 15: transparent colour */
|
||||
outbuf[0] = 0; outbuf[1] = 0; outbuf[2] = 0;
|
||||
fwrite(outbuf, 3, 1, gif_file);
|
||||
|
||||
/* Graphic control extension (8) */
|
||||
/* A graphic control extension block is used for overlay gifs.
|
||||
@ -380,7 +442,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
* 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)));
|
||||
outbuf[9] = 0x00;
|
||||
fwrite(outbuf, 10, 1, gif_file);
|
||||
|
||||
/* call lzw encoding */
|
||||
|
Loading…
Reference in New Issue
Block a user