2015-09-02 6 views
2

- http://www.onicos.com/staff/iz/formats/gif.html#headerКак найти, где начинается Image Block в GIF-изображениях? Источник информации

В GIF изображения фактического размера изображения (ширина, высота) хранится в блоке изображения. Для лучшего понимания Блок изображения - это самый первый блок, включенный в заголовок. Прежде чем начнутся фактические блокировки, будет выделено выделение памяти Глобальная таблица цветов (0..255 x 3 байт) (отныне GCT). Если я могу узнать количество байтов, зарезервированное для GCT Я могу извлечь байты 5-9 из Image Block и иметь фактический размер изображения.

Вопрос: Как я могу знать/узнать, что размер GCT?

ИЛИ

Где GCT конец?

ИЛИ

Где Image Блок начать?

ИЛИ

Где Изображение Блок конец?

ответ

2

Все, что нужно для GIF ENC/дес вы найдете здесь 3MF Project GIF

  1. GCT

    этот блок не является обязательным и не всегда присутствует в GIF файла. Размер определяется количеством цветов и шириной бита от GIF. Я декодировать/загрузить его следующим образом:

    struct _hdr 
        { 
        // Header 
        BYTE Signature[3];  /* Header Signature (always "GIF") */ 
        BYTE Version[3];  /* GIF format version("87a" or "89a") */ 
        // Logical Screen Descriptor 
        WORD xs; 
        WORD ys; 
        BYTE Packed;   /* Screen and Color Map Information */ 
        BYTE BackgroundColor; /* Background Color Index */ 
        BYTE AspectRatio;  /* Pixel Aspect Ratio */ 
        } hdr; 
    
    gcolor_bits= (hdr.Packed &7)+1; // global pallete 
    scolor_bits=((hdr.Packed>>4)&7)+1; // screen 
    _gcolor_sorted =hdr.Packed&8; 
    _gcolor_table =hdr.Packed&128; 
    scolors=1<<scolor_bits; 
    gcolors=1<<gcolor_bits; 
    
    • , если _gcolor_table истинно, то GCT присутствует
    • GCT размер 3*gcolors [Б], сохраненные в порядке R,G,B
  2. Начало изображения

    Это немного сложно, потому что Файлы GIF89a могут содержать много дополнительных блоков. Вам нужно сделать цикл декодирования, определяющий тип блока и декодирование/пропуская его в соответствии с его назначением.Я делаю это так:

    struct _gfxext 
        { 
        BYTE Introducer;  /* Extension Introducer (always 21h) */ 
        BYTE Label;    /* Graphic Control Label (always F9h) */ 
        BYTE BlockSize;   /* Size of remaining fields (always 04h) */ 
        BYTE Packed;   /* Method of graphics disposal to use */ 
        WORD DelayTime;   /* Hundredths of seconds to wait */ 
        BYTE ColorIndex;  /* Transparent Color Index */ 
        BYTE Terminator;  /* Block Terminator (always 0) */ 
        } gfx; 
    
    struct _txtext 
        { 
        BYTE Introducer;  /* Extension Introducer (always 21h) */ 
        BYTE Label;    /* Extension Label (always 01h) */ 
        BYTE BlockSize;   /* Size of Extension Block (always 0Ch) */ 
        WORD TextGridLeft;  /* X position of text grid in pixels */ 
        WORD TextGridTop;  /* Y position of text grid in pixels */ 
        WORD TextGridWidth;  /* Width of the text grid in pixels */ 
        WORD TextGridHeight; /* Height of the text grid in pixels */ 
        BYTE CellWidth;   /* Width of a grid cell in pixels */ 
        BYTE CellHeight;  /* Height of a grid cell in pixels */ 
        BYTE TextFgColorIndex; /* Text foreground color index value */ 
        BYTE TextBgColorIndex; /* Text background color index value */ 
    //  BYTE *PlainTextData; /* The Plain Text data */ 
    //  BYTE Terminator;  /* Block Terminator (always 0) */ 
        }; 
    
    struct _remext 
        { 
        BYTE Introducer;  /* Extension Introducer (always 21h) */ 
        BYTE Label;    /* Comment Label (always FEh) */ 
    //  BYTE *CommentData;  /* Pointer to Comment Data sub-blocks */ 
    //  BYTE Terminator;  /* Block Terminator (always 0) */ 
        }; 
    
    struct _appext 
        { 
        BYTE Introducer;  /* Extension Introducer (always 21h) */ 
        BYTE Label;    /* Extension Label (always FFh) */ 
        BYTE BlockSize;   /* Size of Extension Block (always 0Bh) */ 
        CHAR Identifier[8];  /* Application Identifier */ 
        BYTE AuthentCode[3]; /* Application Authentication Code */ 
    //  BYTE *ApplicationData; /* Point to Application Data sub-blocks */ 
    //  BYTE Terminator;  /* Block Terminator (always 0) */ 
        }; 
    // handle 89a extensions blocks 
    _gfxext gfxext; gfxext.Introducer=0; 
    _txtext txtext; txtext.Introducer=0; 
    _remext remext; remext.Introducer=0; 
    _appext appext; appext.Introducer=0; 
    
    if((hdr.Version[0]=='8') 
    &&(hdr.Version[1]=='9') 
    &&(hdr.Version[2]=='a')) _89a=true; else _89a=false; 
    
    if (_89a) 
    for (;!f.eof;) 
        { 
        f.peek((BYTE*)&dw,2); 
         if (dw==0xF921) { f.read((BYTE*)&gfxext,sizeof(_gfxext)); } 
        else if (dw==0x0121) { f.read((BYTE*)&txtext,sizeof(_txtext)); for (;!f.eof;) { f.read(&db,1); if (!db) break; f.read(dat,DWORD(db)); } } 
        else if (dw==0xFE21) { f.read((BYTE*)&remext,sizeof(_remext)); for (;!f.eof;) { f.read(&db,1); if (!db) break; f.read(dat,DWORD(db)); } } 
        else if (dw==0xFF21) { f.read((BYTE*)&appext,sizeof(_appext)); for (;!f.eof;) { f.read(&db,1); if (!db) break; f.read(dat,DWORD(db)); } } 
        else if ((dw&0x00FF)==0x0021) return; // corrupted file 
        else break;       // no extension found 
        } 
    
    • db является BYTE переменной
    • dw является WORD переменной
    • f моего файл класс кэша члены самообъясняющим Я надеюсь, что в любом случае:
    • f.read(&data,size) чтение size BYTES в data
    • f.peek(&data,size) сделать то же самое, но не обновлять позицию i п файл
    • f.eof указывает конец файла достигнут

    это должно быть сделано для каждого кадра после всего этого заголовка изображения начинается.

  3. Конец изображения

    блок изображения заканчивается терминатором. Все фрагменты изображения начинаются с цифры BYTE. Если это zero, это блок терминатора. Обычно после изображения есть несколько BYTES, которые не используются LZW данных, поэтому после заполнения всей области изображения пропустите все блоки, пока не нажмете блок нулевого размера, а затем остановите это конец изображения. Если BYTE после этого 0x3B шестигранной вы достигли конца GIF файла

[ноты]

Не забудьте герметизировать-структуру с помощью #pragma pack(1) и #pragma pack() или вручную установить Совместите в 1 BYTE , Остерегайтесь проблем со стандартными типами данных (LZW данные без знака), поэтому вы можете избежать ошибок или использовать только неподписанные переменные (с достаточной шириной битов) для декодирования

 Смежные вопросы

  • Нет связанных вопросов^_^