zoukankan      html  css  js  c++  java
  • 不依赖三方库从图像数据中获取宽高-gif、bmp、png、jepg

    int extract_pic_info(const BYTE *pic, const uint32_t size, int &width, int &height)
    {
        int ret = -1;
        width = 0;
        height = 0;
        size_t offset = 0;
        if (pic == NULL)
            return ret;
        if ((pic[0] == 'G') && (pic[1] == 'I') && (pic[2] == 'F') && (pic[3] == '8') && (pic[4] == '9' || '7') && (pic[5] == 'a'))
        {
            //gif
            offset = 6;
            width = MAKEUS(pic[offset + 1], pic[offset]);
            offset += 2;
            height = MAKEUS(pic[offset + 1], pic[offset]);
            ret = 0;
            SS_DEBUG((LM_DEBUG, "extract_pic_info: gif width(%d) height(%d)!
    ", width, height));
        } else if ((pic[0] == 'B') && (pic[1] == 'M'))
        {
            //BMP
            offset = 18;
            width = MAKEUI(pic[offset + 3], pic[offset + 2], pic[offset + 1], pic[offset + 0]);
            offset += 4;
            height = MAKEUS(pic[offset + 1], pic[offset]);
            ret = 0;
            SS_DEBUG((LM_DEBUG, "extract_pic_info: BMP width(%d) height(%d)!
    ", width, height));
        } else if (pic[0] == png_signature[0] && pic[1] == png_signature[1] && pic[2] == png_signature[2] 
                && pic[3] == png_signature [3] && pic[4] == png_signature[4] 
                && pic[5] == png_signature[5] && pic[6] == png_signature[6] && pic[7] == png_signature[7])
        {
            //PNG
            offset = 16;
            width = MAKEUI(pic[offset + 0], pic[offset + 1], pic[offset + 2], pic[offset + 3]);
            offset += 4;
            height = MAKEUI(pic[offset + 0], pic[offset + 1], pic[offset + 2], pic[offset + 3]);
            ret = 0;
            SS_DEBUG((LM_DEBUG, "extract_pic_info: PNG width(%d) height(%d)!
    ", width, height));
        } else if (pic[0] == 255 && pic[1] == 216 && pic[size-2] == 255 && pic[size-1] == 217)
        {
            //JPEG
            bool finish = false;
            offset = 0;
            unsigned char id = 0;
            while(!finish && offset < size)
            {
                if (pic[offset++] != 0xff || offset >= size)
                {
                    ret = -2;
                    SS_DEBUG((LM_DEBUG, "extract_pic_info: JPEG format error!
    "));
                    break;
                }
                id = pic[offset++];
                if (id >= M_APP0 && id <= M_APPF) // app data block
                {
                    offset += MAKEUS(pic[offset], pic[offset + 1]);
                    continue;
                }
                switch(id)
                {
                    case M_SOI:
                        break;
                    case M_COM:
                    case M_DQT:
                    case M_DHT:
                    case M_DNL:
                    case M_DRI:
                        offset += MAKEUS(pic[offset], pic[offset + 1]);
                        break;
                    case M_SOF0:
                        offset += 3;
                        height = MAKEUS(pic[offset], pic[offset + 1]);
                        offset += 2;
                        width = MAKEUS(pic[offset], pic[offset + 1]);
                        finish = true;
                        ret = 0;
                        SS_DEBUG((LM_DEBUG, "extract_pic_info: JPEG width(%d) height(%d)!
    ", width, height));
                        break;
                    case M_SOS:
                    case M_EOI:
                    case M_DATA:
                        finish = true;
                        ret = -1;
                        SS_DEBUG((LM_DEBUG, "extract_pic_info: JPEG can't find SOF0!
    "));
                        break;
                    default:
                        offset += MAKEUS(pic[offset], pic[offset + 1]);
                        break;
                }
            }
        }
        return ret;
    }

    JPEG的每个标记都是由2个字节组成,其前一个字节是固定值0xFF。每个标记之前还可以添加数目不限的0xFF填充字节(fill byte)。下面是其中的8个标记:

    1.   SOI 0xD 图像开始

    2.   APP0 0xE0 JFIF应用数据块

    3.   APPn 0xE1 - 0xEF 其他的应用数据块(n, 1~15)

    4.   DQT 0xDB 量化表

    5.   SOF0 0xC0 帧开始

    6.   DHT 0xC4 霍夫曼(Huffman)表

    7.   SOS 0xDA 扫描线开始

    8.   EOI 0xD9 图像结束

     

  • 相关阅读:
    python的复制,深拷贝和浅拷贝的区别(转)
    linux下ffmpeg安装(转)
    Linux下的tar压缩解压缩命令详解(转)
    centos7安装python-pip(转)
    爬山算法和模拟退火算法简介
    协方差、协方差矩阵定义与计算
    七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)
    Canny边缘检测算法原理及其VC实现详解(二)
    Canny边缘检测算法原理及其VC实现详解(一)
    perforce变量配置与使用
  • 原文地址:https://www.cnblogs.com/zl1991/p/10138319.html
Copyright © 2011-2022 走看看