4da9a48d7c
libwebp 1.6.0's decode + demux path (lossy VP8, lossless VP8L, VP8X container, ALPH alpha, and the WebPDemux/WebPAnimDecoder animation API) amalgamated into one stb-style header, built as portable C99 with all SIMD, threads and host file I/O disabled. amalgamate.py regenerates webpdec.h from a pinned, auto-cloned libwebp checkout; tests/run.sh checks decode output bit-exactly against reference libwebp. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57 lines
2.2 KiB
C
57 lines
2.2 KiB
C
/* exercises the demux + animation API folded into the single header */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define WEBPDEC_IMPLEMENTATION
|
|
#include "webpdec.h"
|
|
|
|
static unsigned char* slurp(const char* p, size_t* n){
|
|
FILE* f=fopen(p,"rb"); if(!f) return 0;
|
|
fseek(f,0,SEEK_END); long L=ftell(f); fseek(f,0,SEEK_SET);
|
|
unsigned char* b=malloc(L); if(fread(b,1,L,f)!=(size_t)L){} fclose(f); *n=L; return b;
|
|
}
|
|
|
|
int main(int argc,char**argv){
|
|
size_t n; unsigned char* buf=slurp(argv[1],&n);
|
|
if(!buf){ printf("no file\n"); return 1; }
|
|
|
|
WebPData data = { buf, n };
|
|
|
|
/* --- demux: report canvas + frame/loop count --- */
|
|
WebPDemuxer* dmux = WebPDemux(&data);
|
|
if(!dmux){ printf("WebPDemux failed\n"); return 1; }
|
|
unsigned cw = WebPDemuxGetI(dmux, WEBP_FF_CANVAS_WIDTH);
|
|
unsigned ch = WebPDemuxGetI(dmux, WEBP_FF_CANVAS_HEIGHT);
|
|
unsigned nf = WebPDemuxGetI(dmux, WEBP_FF_FRAME_COUNT);
|
|
unsigned lp = WebPDemuxGetI(dmux, WEBP_FF_LOOP_COUNT);
|
|
unsigned fl = WebPDemuxGetI(dmux, WEBP_FF_FORMAT_FLAGS);
|
|
printf("demux: canvas=%ux%u frames=%u loop=%u flags=0x%x\n", cw,ch,nf,lp,fl);
|
|
WebPDemuxDelete(dmux);
|
|
|
|
/* --- animation: decode every frame via WebPAnimDecoder --- */
|
|
WebPAnimDecoderOptions opt;
|
|
WebPAnimDecoderOptionsInit(&opt);
|
|
opt.color_mode = MODE_RGBA;
|
|
WebPAnimDecoder* adec = WebPAnimDecoderNew(&data, &opt);
|
|
if(!adec){ printf("WebPAnimDecoderNew failed\n"); return 1; }
|
|
WebPAnimInfo info;
|
|
WebPAnimDecoderGetInfo(adec, &info);
|
|
printf("anim: %ux%u frames=%u loops=%u bgcolor=0x%08x\n",
|
|
info.canvas_width, info.canvas_height, info.frame_count,
|
|
info.loop_count, info.bgcolor);
|
|
int prev = 0, got = 0;
|
|
while (WebPAnimDecoderHasMoreFrames(adec)) {
|
|
uint8_t* frgba; int ts;
|
|
if (!WebPAnimDecoderGetNext(adec, &frgba, &ts)) { printf("GetNext failed\n"); break; }
|
|
long c = ((long)info.canvas_height/2*info.canvas_width + info.canvas_width/2)*4;
|
|
printf(" frame %d ts=%dms (+%dms) centerRGBA=%d,%d,%d,%d\n",
|
|
got, ts, ts-prev, frgba[c],frgba[c+1],frgba[c+2],frgba[c+3]);
|
|
prev = ts; got++;
|
|
}
|
|
printf("decoded %d/%u frames -> %s\n", got, info.frame_count,
|
|
(got==(int)info.frame_count)?"OK":"MISMATCH");
|
|
WebPAnimDecoderDelete(adec);
|
|
free(buf);
|
|
return 0;
|
|
}
|