43#ifndef GIF_TEMP_MALLOC
45#define GIF_TEMP_MALLOC malloc
50#define GIF_TEMP_FREE free
55#define GIF_MALLOC malloc
81int GifIMax(
int l,
int r) {
return l>r?l:r; }
82int GifIMin(
int l,
int r) {
return l<r?l:r; }
94 int ind = treeRoot-(1<<pPal->
bitDepth);
98 int r_err = r - ((int32_t)pPal->
r[ind]);
99 int g_err = g - ((int32_t)pPal->
g[ind]);
100 int b_err = b - ((int32_t)pPal->
b[ind]);
113 int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b;
116 int splitPos = pPal->
treeSplit[treeRoot];
117 if(splitPos > splitComp)
121 if( *bestDiff > splitPos - splitComp )
130 if( *bestDiff > splitComp - splitPos )
139 uint8_t rA =
image[pixA*4];
140 uint8_t gA =
image[pixA*4+1];
141 uint8_t bA =
image[pixA*4+2];
142 uint8_t aA =
image[pixA*4+3];
144 uint8_t rB =
image[pixB*4];
145 uint8_t gB =
image[pixB*4+1];
146 uint8_t bB =
image[pixB*4+2];
147 uint8_t aB =
image[pixA*4+3];
150 image[pixA*4+1] = gB;
151 image[pixA*4+2] = bB;
152 image[pixA*4+3] = aB;
155 image[pixB*4+1] = gA;
156 image[pixB*4+2] = bA;
157 image[pixB*4+3] = aA;
163 const int pivotValue =
image[(pivotIndex)*4+elt];
165 int storeIndex = left;
167 for(
int ii=left; ii<right-1; ++ii)
169 int arrayVal =
image[ii*4+elt];
170 if( arrayVal < pivotValue )
175 else if( arrayVal == pivotValue )
194 int pivotIndex = left + (right-left)/2;
199 if(pivotIndex > neededCenter)
202 if(pivotIndex < neededCenter)
210 if(lastElt <= firstElt || numPixels == 0)
214 if(lastElt == firstElt+1)
224 uint32_t r=255, g=255, b=255;
225 for(
int ii=0; ii<numPixels; ++ii)
232 pal->
r[firstElt] = (uint8_t)r;
233 pal->
g[firstElt] = (uint8_t)g;
234 pal->
b[firstElt] = (uint8_t)b;
239 if( firstElt == (1 << pal->
bitDepth)-1 )
242 uint32_t r=0, g=0, b=0;
243 for(
int ii=0; ii<numPixels; ++ii)
250 pal->
r[firstElt] = (uint8_t)r;
251 pal->
g[firstElt] = (uint8_t)g;
252 pal->
b[firstElt] = (uint8_t)b;
259 uint64_t r=0, g=0, b=0;
260 for(
int ii=0; ii<numPixels; ++ii)
267 r += (uint64_t)numPixels / 2;
268 g += (uint64_t)numPixels / 2;
269 b += (uint64_t)numPixels / 2;
271 r /= (uint64_t)numPixels;
272 g /= (uint64_t)numPixels;
273 b /= (uint64_t)numPixels;
275 pal->
r[firstElt] = (uint8_t)r;
276 pal->
g[firstElt] = (uint8_t)g;
277 pal->
b[firstElt] = (uint8_t)b;
283 int minR = 255, maxR = 0;
284 int minG = 255, maxG = 0;
285 int minB = 255, maxB = 0;
286 for(
int ii=0; ii<numPixels; ++ii)
288 int r =
image[ii*4+0];
289 int g =
image[ii*4+1];
290 int b =
image[ii*4+2];
292 if(r > maxR) maxR = r;
293 if(r < minR) minR = r;
295 if(g > maxG) maxG = g;
296 if(g < minG) minG = g;
298 if(b > maxB) maxB = b;
299 if(b < minB) minB = b;
302 int rRange = maxR - minR;
303 int gRange = maxG - minG;
304 int bRange = maxB - minB;
308 if(bRange > gRange) splitCom = 2;
309 if(rRange > bRange && rRange > gRange) splitCom = 0;
311 int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt);
312 int subPixelsB = numPixels-subPixelsA;
319 GifSplitPalette(
image, subPixelsA, firstElt, splitElt, splitElt-splitDist, splitDist/2, treeNode*2, buildForDither, pal);
320 GifSplitPalette(
image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2+1, buildForDither, pal);
330 uint8_t* writeIter =
frame;
332 for (
int ii=0; ii<numPixels; ++ii)
334 if(lastFrame[0] !=
frame[0] ||
335 lastFrame[1] !=
frame[1] ||
336 lastFrame[2] !=
frame[2])
338 writeIter[0] =
frame[0];
339 writeIter[1] =
frame[1];
340 writeIter[2] =
frame[2];
359 size_t imageSize = (size_t)(width *
height * 4 *
sizeof(uint8_t));
361 memcpy(destroyableImage, nextFrame, imageSize);
363 int numPixels = (int)(width *
height);
367 const int lastElt = 1 << bitDepth;
368 const int splitElt = lastElt/2;
369 const int splitDist = splitElt/2;
371 GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal);
379 pPal->
r[0] = pPal->
g[0] = pPal->
b[0] = 0;
385 int numPixels = (int)(width *
height);
390 int32_t *quantPixels = (int32_t *)
GIF_TEMP_MALLOC(
sizeof(int32_t) * (
size_t)numPixels * 4);
392 for(
int ii=0; ii<numPixels*4; ++ii )
394 uint8_t pix = nextFrame[ii];
395 int32_t pix16 = (int32_t)(pix) * 256;
396 quantPixels[ii] = pix16;
399 for( uint32_t yy=0; yy<
height; ++yy )
401 for( uint32_t xx=0; xx<width; ++xx )
403 int32_t* nextPix = quantPixels + 4*(yy*width+xx);
404 const uint8_t* lastPix = lastFrame? lastFrame + 4*(yy*width+xx) : NULL;
407 int32_t rr = (nextPix[0] + 127) / 256;
408 int32_t gg = (nextPix[1] + 127) / 256;
409 int32_t bb = (nextPix[2] + 127) / 256;
425 int32_t bestDiff = 1000000;
432 int32_t r_err = nextPix[0] - (int32_t)(pPal->
r[bestInd]) * 256;
433 int32_t g_err = nextPix[1] - (int32_t)(pPal->
g[bestInd]) * 256;
434 int32_t b_err = nextPix[2] - (int32_t)(pPal->
b[bestInd]) * 256;
436 nextPix[0] = pPal->
r[bestInd];
437 nextPix[1] = pPal->
g[bestInd];
438 nextPix[2] = pPal->
b[bestInd];
439 nextPix[3] = bestInd;
443 int quantloc_7 = (int)(yy * width + xx + 1);
444 int quantloc_3 = (int)(yy * width + width + xx - 1);
445 int quantloc_5 = (int)(yy * width + width + xx);
446 int quantloc_1 = (int)(yy * width + width + xx + 1);
448 if(quantloc_7 < numPixels)
450 int32_t* pix7 = quantPixels+4*quantloc_7;
451 pix7[0] +=
GifIMax( -pix7[0], r_err * 7 / 16 );
452 pix7[1] +=
GifIMax( -pix7[1], g_err * 7 / 16 );
453 pix7[2] +=
GifIMax( -pix7[2], b_err * 7 / 16 );
456 if(quantloc_3 < numPixels)
458 int32_t* pix3 = quantPixels+4*quantloc_3;
459 pix3[0] +=
GifIMax( -pix3[0], r_err * 3 / 16 );
460 pix3[1] +=
GifIMax( -pix3[1], g_err * 3 / 16 );
461 pix3[2] +=
GifIMax( -pix3[2], b_err * 3 / 16 );
464 if(quantloc_5 < numPixels)
466 int32_t* pix5 = quantPixels+4*quantloc_5;
467 pix5[0] +=
GifIMax( -pix5[0], r_err * 5 / 16 );
468 pix5[1] +=
GifIMax( -pix5[1], g_err * 5 / 16 );
469 pix5[2] +=
GifIMax( -pix5[2], b_err * 5 / 16 );
472 if(quantloc_1 < numPixels)
474 int32_t* pix1 = quantPixels+4*quantloc_1;
475 pix1[0] +=
GifIMax( -pix1[0], r_err / 16 );
476 pix1[1] +=
GifIMax( -pix1[1], g_err / 16 );
477 pix1[2] +=
GifIMax( -pix1[2], b_err / 16 );
483 for(
int ii=0; ii<numPixels*4; ++ii )
485 outFrame[ii] = (uint8_t)quantPixels[ii];
494 uint32_t numPixels = width*
height;
495 for( uint32_t ii=0; ii<numPixels; ++ii )
500 lastFrame[0] == nextFrame[0] &&
501 lastFrame[1] == nextFrame[1] &&
502 lastFrame[2] == nextFrame[2])
504 outFrame[0] = lastFrame[0];
505 outFrame[1] = lastFrame[1];
506 outFrame[2] = lastFrame[2];
512 int32_t bestDiff = 1000000;
517 outFrame[0] = pPal->
r[bestInd];
518 outFrame[1] = pPal->
g[bestInd];
519 outFrame[2] = pPal->
b[bestInd];
520 outFrame[3] = (uint8_t)bestInd;
523 if(lastFrame) lastFrame += 4;
571 for( uint32_t ii=0; ii<length; ++ii )
597 for(
int ii=1; ii<(1 << pPal->
bitDepth); ++ii)
599 uint32_t r = pPal->
r[ii];
600 uint32_t g = pPal->
g[ii];
601 uint32_t b = pPal->
b[ii];
617 fputc(delay & 0xff,
f);
618 fputc((delay >> 8) & 0xff,
f);
624 fputc(left & 0xff,
f);
625 fputc((left >> 8) & 0xff,
f);
626 fputc(top & 0xff,
f);
627 fputc((top >> 8) & 0xff,
f);
629 fputc(width & 0xff,
f);
630 fputc((width >> 8) & 0xff,
f);
632 fputc((
height >> 8) & 0xff,
f);
640 const int minCodeSize = pPal->
bitDepth;
641 const uint32_t clearCode = 1 << pPal->
bitDepth;
643 fputc(minCodeSize,
f);
648 int32_t curCode = -1;
649 uint32_t codeSize = (uint32_t)minCodeSize + 1;
650 uint32_t maxCode = clearCode+1;
659 for(uint32_t yy=0; yy<
height; ++yy)
661 for(uint32_t xx=0; xx<width; ++xx)
665 uint8_t nextValue =
image[((
height-1-yy)*width+xx)*4+3];
668 uint8_t nextValue =
image[(yy*width+xx)*4+3];
680 else if( codetree[curCode].m_next[nextValue] )
683 curCode = codetree[curCode].
m_next[nextValue];
691 codetree[curCode].
m_next[nextValue] = (uint16_t)++maxCode;
693 if( maxCode >= (1ul << codeSize) )
699 if( maxCode == 4095 )
705 codeSize = (uint32_t)(minCodeSize + 1);
706 maxCode = clearCode+1;
717 GifWriteCode(
f, &stat, clearCode + 1, (uint32_t)minCodeSize + 1);
738bool GifBegin(
GifWriter* writer,
const char* filename, uint32_t width, uint32_t
height, uint32_t delay, int32_t bitDepth = 8,
bool dither =
false )
740 (void)bitDepth; (void)dither;
741#if defined(_MSC_VER) && (_MSC_VER >= 1400)
743 fopen_s(&writer->
f, filename,
"wb");
745 writer->
f = fopen(filename,
"wb");
747 if(!writer->
f)
return false;
754 fputs(
"GIF89a", writer->
f);
757 fputc(width & 0xff, writer->
f);
758 fputc((width >> 8) & 0xff, writer->
f);
759 fputc(
height & 0xff, writer->
f);
760 fputc((
height >> 8) & 0xff, writer->
f);
762 fputc(0xf0, writer->
f);
779 fputc(0x21, writer->
f);
780 fputc(0xff, writer->
f);
781 fputc(11, writer->
f);
782 fputs(
"NETSCAPE2.0", writer->
f);
801 if(!writer->
f)
return false;
824 if(!writer->
f)
return false;
826 fputc(0x3b, writer->
f);
void split(std::vector< FontInterfaceImpl::Bezier2d > &vec, FontInterfaceImpl::Bezier2d orig, float t, bool emit_left, bool emit_right)
Definition FreeType2.cc:134
std::string code
Definition test.cpp:145
frame( $arr, $width, $height, $data, $i, $homepage, $noheaders, $seamless, $transparent)
Definition emscripten_frame.php:18
#define GIF_MALLOC
Definition gif.h:55
void GifWriteLzwImage(FILE *f, uint8_t *image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette *pPal)
Definition gif.h:610
void GifWritePalette(const GifPalette *pPal, FILE *f)
Definition gif.h:591
void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int *bestInd, int *bestDiff, int treeRoot)
Definition gif.h:89
void GifWriteBit(GifBitStatus *stat, uint32_t bit)
Definition gif.h:541
#define GIF_TEMP_FREE
Definition gif.h:50
void GifThresholdImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal)
Definition gif.h:492
bool GifWriteFrame(GifWriter *writer, const uint8_t *image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth=8, bool dither=false)
Definition gif.h:799
void GifDitherImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal)
Definition gif.h:383
const int kGifTransIndex
Definition gif.h:63
#define GIF_FREE
Definition gif.h:60
int GifIAbs(int i)
Definition gif.h:83
void GifWriteChunk(FILE *f, GifBitStatus *stat)
Definition gif.h:559
bool GifEnd(GifWriter *writer)
Definition gif.h:822
int GifPartition(uint8_t *image, const int left, const int right, const int elt, int pivotIndex)
Definition gif.h:161
bool GifBegin(GifWriter *writer, const char *filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth=8, bool dither=false)
Definition gif.h:738
void GifSwapPixels(uint8_t *image, int pixA, int pixB)
Definition gif.h:137
void GifWriteCode(FILE *f, GifBitStatus *stat, uint32_t code, uint32_t length)
Definition gif.h:569
#define GIF_TEMP_MALLOC
Definition gif.h:45
void GifPartitionByMedian(uint8_t *image, int left, int right, int com, int neededCenter)
Definition gif.h:190
void GifMakePalette(const uint8_t *lastFrame, const uint8_t *nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette *pPal)
Definition gif.h:353
int GifIMin(int l, int r)
Definition gif.h:82
int GifPickChangedPixels(const uint8_t *lastFrame, uint8_t *frame, int numPixels)
Definition gif.h:327
int GifIMax(int l, int r)
Definition gif.h:81
void GifSplitPalette(uint8_t *image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette *pal)
Definition gif.h:208
line height
Definition meshpage.php:3536
background image
Definition meshpage_bootstrap.php:1723
double f(const std::string &, double, bool) noexcept
Definition profile_cpp_calls_2.cpp:4
uint32_t chunkIndex
Definition gif.h:536
uint8_t chunk[256]
Definition gif.h:537
uint8_t byte
Definition gif.h:534
uint8_t bitIndex
Definition gif.h:533
uint16_t m_next[256]
Definition gif.h:587
uint8_t b[256]
Definition gif.h:71
uint8_t treeSplitElt[256]
Definition gif.h:76
uint8_t r[256]
Definition gif.h:69
int bitDepth
Definition gif.h:67
uint8_t g[256]
Definition gif.h:70
uint8_t treeSplit[256]
Definition gif.h:77
FILE * f
Definition gif.h:730
uint8_t * oldImage
Definition gif.h:731
bool firstFrame
Definition gif.h:732