找回密码
 立即注册
查看: 2637|回复: 5

[C++]giflib Chrome使用实例

[复制链接]

587

回帖

682

基友

5877

积分

死神左手

Rank: 16Rank: 16Rank: 16Rank: 16

发表于 2014-2-3 15:10:59 | 显示全部楼层 |阅读模式
  1. /** libs/graphics/images/SkImageDecoder_libgif.cpp
  2. **
  3. ** Copyright 2006, The Android Open Source Project
  4. **
  5. ** Licensed under the Apache License, Version 2.0 (the "License");
  6. ** you may not use this file except in compliance with the License.
  7. ** You may obtain a copy of the License at
  8. **
  9. **     http://www.apache.org/licenses/LICENSE-2.0
  10. **
  11. ** Unless required by applicable law or agreed to in writing, software
  12. ** distributed under the License is distributed on an "AS IS" BASIS,
  13. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ** See the License for the specific language governing permissions and
  15. ** limitations under the License.
  16. */

  17. #include "SkMovie.h"
  18. #include "SkColor.h"
  19. #include "SkColorPriv.h"
  20. #include "SkStream.h"
  21. #include "SkTemplates.h"

  22. #include "gif_lib.h"

  23. class SkGIFMovie : public SkMovie {
  24. public:
  25.     SkGIFMovie(SkStream* stream);
  26.     virtual ~SkGIFMovie();

  27. protected:
  28.     virtual bool onGetInfo(Info*);
  29.     virtual bool onSetTime(SkMSec);
  30.     virtual bool onGetBitmap(SkBitmap*);
  31.    
  32. private:
  33.     GifFileType* fGIF;
  34.     SavedImage* fCurrSavedImage;
  35. };

  36. static int Decode(GifFileType* fileType, GifByteType* out, int size) {
  37.     SkStream* stream = (SkStream*) fileType->UserData;
  38.     return (int) stream->read(out, size);
  39. }

  40. SkGIFMovie::SkGIFMovie(SkStream* stream)
  41. {
  42.     fGIF = DGifOpen( stream, Decode );
  43.     if (NULL == fGIF)
  44.         return;

  45.     if (DGifSlurp(fGIF) != GIF_OK)
  46.     {
  47.         DGifCloseFile(fGIF);
  48.         fGIF = NULL;
  49.     }
  50.     fCurrSavedImage = NULL;
  51. }

  52. SkGIFMovie::~SkGIFMovie()
  53. {
  54.     if (fGIF)
  55.         DGifCloseFile(fGIF);
  56. }

  57. static SkMSec savedimage_duration(const SavedImage* image)
  58. {
  59.     for (int j = 0; j < image->ExtensionBlockCount; j++)
  60.     {
  61.         if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE)
  62.         {
  63.             int size = image->ExtensionBlocks[j].ByteCount;
  64.             SkASSERT(size >= 4);
  65.             const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes;
  66.             return ((b[2] << 8) | b[1]) * 10;
  67.         }
  68.     }
  69.     return 0;
  70. }

  71. bool SkGIFMovie::onGetInfo(Info* info)
  72. {
  73.     if (NULL == fGIF)
  74.         return false;

  75.     SkMSec dur = 0;
  76.     for (int i = 0; i < fGIF->ImageCount; i++)
  77.         dur += savedimage_duration(&fGIF->SavedImages[i]);

  78.     info->fDuration = dur;
  79.     info->fWidth = fGIF->SWidth;
  80.     info->fHeight = fGIF->SHeight;
  81.     info->fIsOpaque = false;    // how to compute?
  82.     return true;
  83. }

  84. bool SkGIFMovie::onSetTime(SkMSec time)
  85. {
  86.     if (NULL == fGIF)
  87.         return false;

  88.     SkMSec dur = 0;
  89.     for (int i = 0; i < fGIF->ImageCount; i++)
  90.     {
  91.         dur += savedimage_duration(&fGIF->SavedImages[i]);
  92.         if (dur >= time)
  93.         {
  94.             SavedImage* prev = fCurrSavedImage;
  95.             fCurrSavedImage = &fGIF->SavedImages[i];
  96.             return prev != fCurrSavedImage;
  97.         }
  98.     }
  99.     fCurrSavedImage = &fGIF->SavedImages[fGIF->ImageCount - 1];
  100.     return true;
  101. }

  102. bool SkGIFMovie::onGetBitmap(SkBitmap* bm)
  103. {
  104.     GifFileType* gif = fGIF;
  105.     if (NULL == gif)
  106.         return false;

  107.     // should we check for the Image cmap or the global (SColorMap) first?
  108.     ColorMapObject* cmap = gif->SColorMap;
  109.     if (cmap == NULL)
  110.         cmap = gif->Image.ColorMap;

  111.     if (cmap == NULL || gif->ImageCount < 1 || cmap->ColorCount != (1 << cmap->BitsPerPixel))
  112.     {
  113.         SkASSERT(!"bad colortable setup");
  114.         return false;
  115.     }

  116.     const int width = gif->SWidth;
  117.     const int height = gif->SHeight;
  118.     if (width <= 0 || height <= 0) {
  119.         return false;
  120.     }

  121.     SavedImage*      gif_image = fCurrSavedImage;
  122.     SkBitmap::Config config = SkBitmap::kIndex8_Config;

  123.     SkColorTable* colorTable = SkNEW_ARGS(SkColorTable, (cmap->ColorCount));
  124.     SkAutoUnref aur(colorTable);

  125.     bm->setConfig(config, width, height, 0);
  126.     if (!bm->allocPixels(colorTable)) {
  127.         return false;
  128.     }

  129.     int transparent = -1;
  130.     for (int i = 0; i < gif_image->ExtensionBlockCount; ++i) {
  131.       ExtensionBlock* eb = gif_image->ExtensionBlocks + i;
  132.       if (eb->Function == 0xF9 &&
  133.           eb->ByteCount == 4) {
  134.         bool has_transparency = ((eb->Bytes[0] & 1) == 1);
  135.         if (has_transparency) {
  136.           transparent = (unsigned char)eb->Bytes[3];
  137.         }
  138.       }
  139.     }

  140.     SkPMColor* colorPtr = colorTable->lockColors();

  141.     if (transparent >= 0)
  142.         memset(colorPtr, 0, cmap->ColorCount * 4);
  143.     else
  144.         colorTable->setFlags(colorTable->getFlags() | SkColorTable::kColorsAreOpaque_Flag);

  145.     for (int index = 0; index < cmap->ColorCount; index++)
  146.     {
  147.         if (transparent != index)
  148.             colorPtr[index] = SkPackARGB32(0xFF, cmap->Colors[index].Red,
  149.                 cmap->Colors[index].Green, cmap->Colors[index].Blue);
  150.     }
  151.     colorTable->unlockColors(true);

  152.     unsigned char* in = (unsigned char*)gif_image->RasterBits;
  153.     unsigned char* out = bm->getAddr8(0, 0);
  154.     if (gif->Image.Interlace) {

  155.       // deinterlace
  156.         int row;
  157.       // group 1 - every 8th row, starting with row 0
  158.       for (row = 0; row < height; row += 8) {
  159.         memcpy(out + width * row, in, width);
  160.         in += width;
  161.       }

  162.       // group 2 - every 8th row, starting with row 4
  163.       for (row = 4; row < height; row += 8) {
  164.         memcpy(out + width * row, in, width);
  165.         in += width;
  166.       }

  167.       // group 3 - every 4th row, starting with row 2
  168.       for (row = 2; row < height; row += 4) {
  169.         memcpy(out + width * row, in, width);
  170.         in += width;
  171.       }

  172.       for (row = 1; row < height; row += 2) {
  173.         memcpy(out + width * row, in, width);
  174.         in += width;
  175.       }

  176.     } else {
  177.       memcpy(out, in, width * height);
  178.     }
  179.     return true;
  180. }

  181. ///////////////////////////////////////////////////////////////////////////////

  182. #include "SkTRegistry.h"

  183. SkMovie* Factory(SkStream* stream) {
  184.     char buf[GIF_STAMP_LEN];
  185.     if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
  186.         if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
  187.                 memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
  188.                 memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
  189.             // must rewind here, since our construct wants to re-read the data
  190.             stream->rewind();
  191.             return SkNEW_ARGS(SkGIFMovie, (stream));
  192.         }
  193.     }
  194.     return NULL;
  195. }

  196. static SkTRegistry<SkMovie*, SkStream*> gReg(Factory);
复制代码
此文件路径为 chromium/third_party/skia/src/images/SkMovie_gif.cpp 来自Chrome



回复

使用道具 举报

1568

回帖

1万

基友

1万

积分

仙人2层 Lv.11

Rank: 6Rank: 6

发表于 2014-2-3 16:07:27 | 显示全部楼层
看不懂0.0
回复 支持 反对

使用道具 举报

1万

回帖

6412

基友

3万

积分

死神左手

纯白无邪

Rank: 16Rank: 16Rank: 16Rank: 16

二货勋章周年纪念勋章

发表于 2014-2-3 16:51:41 | 显示全部楼层
么么哒
回复 支持 反对

使用道具 举报

187

回帖

1301

基友

1948

积分

通神3段 Lv.6

Rank: 3Rank: 3

发表于 2014-3-10 11:24:20 | 显示全部楼层
c++太复杂 不如易语言
回复 支持 反对

使用道具 举报

587

回帖

682

基友

5877

积分

死神左手

Rank: 16Rank: 16Rank: 16Rank: 16

 楼主| 发表于 2014-3-20 11:15:52 | 显示全部楼层
ssfs333asas 发表于 2014-3-10 11:24
c++太复杂 不如易语言

呵呵,易语言有哪个大型项目?请举例说明。
回复 支持 反对

使用道具 举报

280

回帖

-10

基友

190

积分

凡人2阶 Lv.2

Rank: 1

发表于 2014-5-16 11:16:59 | 显示全部楼层
逛逛
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|苍海国际 ( 鲁ICP备13020644号-1 )

GMT+8, 2024-11-22 06:49 , Processed in 0.055399 second(s), 27 queries .

Powered by Discuz! Theme By eRic Modified by 4bpa

© CangHai International We Do Our Rights!

返回顶部