根据 【19-使用giflib处理GIF图片】 ,使用 giflib 库来完成 .gif to RGB。
int decodeGIF(char *filename, unsigned char **gifRGB) { int i, j, Size, Row, Col, Width, Height, ExtCode, Count; GifRecordType RecordType; GifByteType *Extension; GifRowType *ScreenBuffer; GifFileType *GifFile; int InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */ InterlacedJumps[] = { 8, 8, 4, 2 }; /* be read - offsets and jumps... */ int ImageNum = 0; ColorMapObject *ColorMap; int Error; if ((GifFile = DGifOpenFileName(filename, &Error)) == NULL) { printf("Open File Error.\n"); return -1; } if (GifFile->SHeight == 0 || GifFile->SWidth == 0) { printf("Image of width or height 0\n"); return -1; } /* * Allocate the screen as vector of column of rows. Note this * screen is device independent - it's the screen defined by the * GIF file parameters. */ if ((ScreenBuffer = (GifRowType *) malloc(GifFile->SHeight * sizeof(GifRowType))) == NULL) { printf("Failed to allocate memory required, aborted.\n"); return -1; } Size = GifFile->SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/ if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) { /* First row. */ printf("Failed to allocate memory required, aborted.\n"); return -1; } for (i = 0; i < GifFile->SWidth; i++) /* Set its color to BackGround. */ ScreenBuffer[0][i] = GifFile->SBackGroundColor; for (i = 1; i < GifFile->SHeight; i++) { /* Allocate the other rows, and set their color to background too: */ if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) { printf("Failed to allocate memory required, aborted.\n"); return -1; } memcpy(ScreenBuffer[i], ScreenBuffer[0], Size); } int screenIndex = 0; /* Scan the content of the GIF file and load the image(s) in: */ do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) { printf("DGifGetRecordType Error.\n"); return -1; } switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) { printf("DGifGetImageDesc Error.\n"); return -1; } Row = GifFile->Image.Top; /* Image Position relative to Screen. */ Col = GifFile->Image.Left; Width = GifFile->Image.Width; Height = GifFile->Image.Height; if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth || GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) { printf("Image %d is not confined to screen dimension, aborted.\n",ImageNum); return -1; } if (GifFile->Image.Interlace) { /* Need to perform 4 passes on the images: */ for (Count = i = 0; i < 4; i++) for (j = Row + InterlacedOffset[i]; j < Row + Height; j += InterlacedJumps[i]) { if (DGifGetLine(GifFile, &ScreenBuffer[j][Col], Width) == GIF_ERROR) { printf("DGifGetLine Error.\n"); return -1; } } } else { for (i = 0; i < Height; i++) { if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col], Width) == GIF_ERROR) { printf("DGifGetLine Error.\n"); return -1; } } } /* Lets dump it - set the global variables required and do it: */ ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap); if (ColorMap == NULL) { fprintf(stderr, "Gif Image does not have a colormap\n"); exit(EXIT_FAILURE); } /* check that the background color isn't garbage (SF bug #87) */ if (GifFile->SBackGroundColor < 0 || GifFile->SBackGroundColor >= ColorMap->ColorCount) { printf("Background color out of range for colormap\n"); return -1; } GifRowType GifRow; GifColorType *ColorMapEntry; unsigned char *BufferP; *gifRGB = malloc(GifFile->SWidth*GifFile->SHeight*3); for (i = 0; i < GifFile->SHeight; i++) { GifRow = ScreenBuffer[i]; for (j = 0, BufferP = *gifRGB+GifFile->SWidth*3*i; j < GifFile->SWidth; j++) { ColorMapEntry = &ColorMap->Colors[GifRow[j]]; *BufferP++ = ColorMapEntry->Red; *BufferP++ = ColorMapEntry->Green; *BufferP++ = ColorMapEntry->Blue; } } break; case EXTENSION_RECORD_TYPE: /* Skip any extension blocks in file: */ if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) { printf("DGifGetExtension Error.\n"); return -1; } while (Extension != NULL) { if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) { printf("DGifGetExtensionNext Error.\n"); return -1; } } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType. */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); (void)free(ScreenBuffer); if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) { printf("DGifCloseFile Error.\n"); return -1; } return 0; } RGB 查看 ffplay -f rawvideo -pixel_format rgb24 -video_size 400x400 texture.rgb RGB to GIF音视频入门-20-BMP、PNG、JPG、GIF静态图生成GIF动态图 (2)
内容版权声明:除非注明,否则皆为本站原创文章。