判断内存中的数据块是否是合法的jpg或png格式的数据。

实现这个功能需要imageHelper.h imageHelper.cpp这两个源代码文件

imageHelper.h

#ifndef _IMAGE_HELPER_H_
#define _IMAGE_HELPER_H_

/*
Title: Image Helper
Author: kagula
Date: 2018-10-3
Function Description:
  用来判断内存中的数据是不是合法的ipng或jpg文件!
Test Environment:
  [1]Win10 Pro with visual studio 2017 community
  [2]CentOS7 with gcc 5.x
Dependencies:
  [1]libjpeg9c
  [2]libpng-libpng16
  [3]zlib 1.2.8
How to use:
  使用前先把jpg/png文件的内容读到DataBlock实例中,
然后,就可以使用IsValidJPG和IsValidPNG来判断文件格式是否正确了。
  
*/

namespace kagula
{
	struct DataBlock;
	
	bool IsValidJPG(DataBlock &db);
	bool IsValidPNG(DataBlock &db);
}

#endif // _DEBUG

imageHelper.cpp

#include "imageHelper.h"
#include "fileHelper.h"

#include <png.h>
#include <zlib.h>

#ifdef _WIN32
#pragma comment(lib,"libjpeg9c.lib")
#ifdef _DEBUG
#pragma comment(lib,"libpng16d.lib")
#pragma comment(lib,"zlibd.lib")
#else
#pragma comment(lib,"libpng16.lib")
#pragma comment(lib,"zlib.lib")
#endif
#endif // DEBUG

#include "../libjpeg9c/jpeglib.h"
#include "cderror.h"

#define JMESSAGE(code,string)	string ,

static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
	nullptr
};

namespace kagula
{
	bool IsValidJPG(DataBlock &db)
	{
		bool isOK = false;

		struct jpeg_decompress_struct cinfo;
		struct jpeg_error_mgr jerr;

		/* Initialize the JPEG decompression object with default error handling. */
		cinfo.err = jpeg_std_error(&jerr);
		jpeg_create_decompress(&cinfo);

		/* Add some application-specific error messages (from cderror.h) */
		jerr.addon_message_table = cdjpeg_message_table;
		jerr.first_addon_message = ADDON_MESSAGE_CODE::JMSG_FIRSTADDONCODE;
		jerr.last_addon_message = ADDON_MESSAGE_CODE::JMSG_LASTADDONCODE;

		/* Specify data source for decompression */
		jpeg_mem_src(&cinfo, db.pData,db.length);

		/* Read file header, set default decompression parameters */
		(void)jpeg_read_header(&cinfo, TRUE);//如果不是合法的jpg文件,这段代码会挂掉。

		if (cinfo.image_width > 0 && cinfo.image_height > 0)
		{
			isOK = true;
		}

		jpeg_destroy_decompress(&cinfo);

		return isOK;
	}

	typedef struct {
		unsigned char *data;
		unsigned int size;
		unsigned int offset;
	}ImageSource;

	static void pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
	{
		ImageSource *is = (ImageSource*)png_get_io_ptr(png_ptr);

		if (is->offset + length <= is->size)
		{
			memcpy(data, is->data + is->offset, length);
			is->offset += length;
		}
		else
		{
			png_error(png_ptr, "pngReaderCallback failed.");
		}
	}

	png_uint_32 width, height;
	ImageSource srcImg;
	int color_type;
	bool IsValidPNG(DataBlock &db)
	{
		png_structp png_ptr;
		png_infop info_ptr;
		int bit_depth;
		FILE *fp;

		//printf("lpng[%s], zlib[%s]\n", PNG_LIBPNG_VER_STRING, ZLIB_VERSION);
		png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
		if (png_ptr == NULL)
		{
			return false;
		}
		info_ptr = png_create_info_struct(png_ptr);
		if (info_ptr == NULL)
		{
			png_destroy_read_struct(&png_ptr, NULL, NULL);
			return false;
		}
		if (setjmp(png_jmpbuf(png_ptr))) {
			/* Free all of the memory associated with the png_ptr and info_ptr */
			png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
			/* If we get here, we had a problem reading the file */
			return false;
		}

		//定义被移到了global scope.
		srcImg.data = db.pData;
		srcImg.size = db.length;
		srcImg.offset = 0;
		png_set_read_fn(png_ptr, &srcImg, pngReadCallback);

		png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);

		//获取png图片相关信息  
		png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
			NULL, NULL, NULL);

		//printf("width[%d], height[%d], bit_depth[%d], color_type[%d]\n",
			//width, height, bit_depth, color_type);

		png_destroy_read_struct(&png_ptr, &info_ptr, 0);
		
		return true;
	}
}

imageHelper的定义需要struct DataBlock的声明和实现,

下面是DataBlock的声明和实现:

	struct DataBlock {
		unsigned char *pData;
		unsigned long long length;
		DataBlock() :pData(nullptr), length(0) {}
		~DataBlock() {
			if (pData != nullptr)
			{
				delete pData;
				length = 0;
			}
		}
	};//struct

猜你喜欢

转载自blog.csdn.net/lee353086/article/details/82929802