编程技术记录

世界你好!

通过读取png图像文件的头信息

#include "stdio.h"

namespace {
    class CFileStream
    {
    public:
        CFileStream (FILE *fs):m_fs(fs)
        {}

        ~CFileStream()
        {
            fclose(m_fs);
        }

        inline operator FILE*()
        {
            return  m_fs;
        }
        inline operator bool()
        {
            return  m_fs != 0;
        }
    private:
        FILE *m_fs;
    };

    inline unsigned long Convert4char( unsigned char c[4]) //网络端字节序
    {
        unsigned long n = ((unsigned long)c[0]) << 24;
        n += ((unsigned long)c[1]) << 16;
        n += ((unsigned long)c[2]) << 8;
        n += ((unsigned long)c[3]);
        return n;
    }
}

#define png_signature_len 8 //png文件签名
#define png_chunk_len_len  4 //idhr长度信息
#define png_chunk_type_len 4 //ihdr类型码
#define png_ihdr_data_len 13 //ihdr数据

+ (BOOL)imageSizeFromPNGFile:(NSString *)pngFile size:(CGSize *)size;
{
    if (!pngFile || !size) {
        return NO;
    }

    CFileStream fs = fopen([pngFile UTF8String], "rb");
    if (!fs) {
        return NO;
    }

    unsigned char buf[png_signature_len+png_chunk_len_len+png_chunk_type_len+png_ihdr_data_len];
    if (sizeof(buf) != fread(buf, 1, sizeof(buf), fs)) {
        return NO;
    }
    //校验文件签名
    if ( memcmp(buf, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", png_signature_len) != 0 ) {
        return NO;
    }
    //校验ihdr长度
    if (memcmp(buf + png_signature_len, "\x00\x00\x00\x0d", png_chunk_len_len) != 0) {
        return NO;
    }
    //校验ihdr类型码
    if (memcmp(buf + png_signature_len +png_chunk_len_len, "IHDR", png_chunk_len_len) != 0) {
        return NO;
    }

    size->width = Convert4char(buf + png_signature_len+png_chunk_len_len+png_chunk_type_len );
    size->height = Convert4char(buf + png_signature_len+png_chunk_len_len+png_chunk_type_len+4);

    return YES;
}
#undef png_signature_len
#undef png_chunk_len_len
#undef png_chunk_type_len
#undef png_ihdr_data_len

发表回复

© Beli. All Rights Reserved.