I want to extract gif frames to raw BGRA data, I used giflib to parse format. I've got first frame (I suppose it's like a key frame in video) that looks good and second (it's 15 frames actually, but let's simplify it) that looks like diff frame. Here is samples:
It seems to be simple to restore second full frame using diff data, but here is the problem: I have no idea what color index means "Not changed". Black pixels on diff frame is actually black – its index in color map is 255, which is rgb(0,0,0). I printed whole color table and didn't found any other black entries. It's here if interested. "BackgroundColor" index is 193, so it makes no sense either.
So, I can't separate "black" color from "no" color. What if second frame will really contain some new black pixels (it contains indeed because left eye moves on animation)? But program should handles it differently: get previous frame color for "no" color and get rgb(0,0,0) for "black" color.
UPD: here is my code. Subframes handling and memory cleanup is ommited. Here I supposed that "no" color index is last in colortable. It works actually for my test file, but I'm not sure it will work in general.
DGifSlurp(image);
int* master = malloc(image->SWidth * image->SHeight * sizeof(int));
for (int i = 0; i < image->ImageCount; i++) {
SavedImage* frame = &image->SavedImages[i];
ColorMapObject* cmap = frame->ImageDesc.ColorMap ? frame->ImageDesc.ColorMap : image->SColorMap;
int nocoloridx = cmap->ColorCount - 1;
IplImage* mat = cvCreateImage(cvSize(frame->ImageDesc.Width, frame->ImageDesc.Height), IPL_DEPTH_8U, 4);
mat->imageData = malloc(frame->ImageDesc.Width * frame->ImageDesc.Height * 4);
for (int y = 0; y < frame->ImageDesc.Height; y++)
for (int x = 0; x < frame->ImageDesc.Width; x++) {
int offset = y * frame->ImageDesc.Width + x;
int coloridx = frame->RasterBits[offset];
if (coloridx == nocoloridx) {
coloridx = master[offset];
} else {
master[offset] = coloridx;
}
GifColorType color = cmap->Colors[coloridx];
cvSetComponent(mat, x, y, 0, color.Blue);
cvSetComponent(mat, x, y, 1, color.Green);
cvSetComponent(mat, x, y, 2, color.Red);
cvSetComponent(mat, x, y, 3, 100);
}
cvNamedWindow("t", CV_WINDOW_AUTOSIZE);
cvShowImage("t", mat);
cvWaitKey(0);
}