⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opengif.cpp

📁 这个刚才那个的源代码
💻 CPP
字号:
#include <stdio.h>
#include <string.h>
extern "C" {
  #include <gif_lib.h>
}
#include "Debug.h"
#include "Open.h"
#include "SimpleImage.h"
#include "Utility.h"


namespace corona {

  int InputFunc(GifFileType* gif, GifByteType* bytes, int size) {
    File* file = (File*)gif->UserData;
    return file->read(bytes, size);
  }

  Image* OpenGIF(File* file) {
    COR_GUARD("OpenGIF");

    // open GIF file
    GifFileType* gif = DGifOpen(file, InputFunc);
    if (!gif) {
      COR_LOG("DGifOpen failed");
      return 0;
    }

    // read GIF image
    if (DGifSlurp(gif) != GIF_OK) {
      COR_LOG("DGifSlurp failed");
      DGifCloseFile(gif);
      return 0;
    }
    ColorMapObject* cmap = gif->SColorMap;

    // validate attributes
    if (cmap == 0 ||
        gif->ImageCount < 1 ||
        cmap->ColorCount != (1 << cmap->BitsPerPixel))
    {
      COR_IF_DEBUG {
        char str[1024];
        sprintf(str, "incorrect gif attributes:\n");
        sprintf(str + strlen(str), " ImageCount: %d\n", gif->ImageCount);
        if (cmap) {
          sprintf(str + strlen(str), " BitsPerPixel: %d\n", cmap->BitsPerPixel);
          sprintf(str + strlen(str), " ColorCount: %d\n", cmap->ColorCount);
        }
        COR_LOG(str);
      }
      
      DGifCloseFile(gif);
      return 0;
    }

    // use the first frame of the animation
    SavedImage* gif_image = gif->SavedImages + 0;

    const int width = gif->SWidth;
    const int height = gif->SHeight;
    auto_array<byte> image(new byte[width * height]);
    auto_array<RGBA> palette(new RGBA[256]);

    // look for the transparent color extension
    int transparent = -1;
    for (int i = 0; i < gif_image->ExtensionBlockCount; ++i) {
      ExtensionBlock* eb = gif_image->ExtensionBlocks + i;
      if (eb->Function == 0xF9 && 
          eb->ByteCount == 4) {
        bool has_transparency = ((eb->Bytes[0] & 1) == 1);
        if (has_transparency) {
          transparent = eb->Bytes[3];
        }
      }
    }

    // copy over the palette
    memset(palette, 0, 256 * 4);
    for (int i = 0; i < cmap->ColorCount; ++i) {
      palette[i].red   = cmap->Colors[i].Red;
      palette[i].green = cmap->Colors[i].Green;
      palette[i].blue  = cmap->Colors[i].Blue;
      palette[i].alpha = (transparent == i ? 0 : 255);
    }

    byte* in = (byte*)gif_image->RasterBits;
    byte* out = image;
    if (gif->Image.Interlace) {

      // deinterlace

      // group 1 - every 8th row, starting with row 0
      for (int row = 0; row < height; row += 8) {
        memcpy(out + width * row, in, width);
        in += width;
      }

      // group 2 - every 8th row, starting with row 4
      for (int row = 4; row < height; row += 8) {
        memcpy(out + width * row, in, width);
        in += width;
      }

      // group 3 - every 4th row, starting with row 2
      for (int row = 2; row < height; row += 4) {
        memcpy(out + width * row, in, width);
        in += width;
      }

      for (int row = 1; row < height; row += 2) {
        memcpy(out + width * row, in, width);
        in += width;
      }

    } else {
      memcpy(out, in, width * height);
    }

    DGifCloseFile(gif);
    return new SimpleImage(width, height, PF_I8, image.release(),
                           (byte*)palette.release(), 256, PF_R8G8B8A8);
  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -