⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winimage.cpp

📁 smartphone 监听电源状态源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

// ****************************************************************************
//
// WINIMAGE.CPP : Generic classes for raster images (MSWindows specialization)
//
//  Content: Member definitions for:
//  - class C_Image             : Storage class for single images
//  - class C_ImageSet          : Storage class for sets of images
//  - class C_AnimationWindow   : Window Class to display animations
//
//  (Includes routines to Load and Save BMP files and to load GIF files into
// these classes).
//
//  --------------------------------------------------------------------------
//
// Copyright ?2000, Juan Soulie <jsoulie@cplusplus.com>
//
// Permission to use, copy, modify, distribute and sell this software or any
// part thereof and/or its documentation for any purpose is granted without fee
// provided that the above copyright notice and this permission notice appear
// in all copies.
//
// This software is provided "as is" without express or implied warranty of
// any kind. The author shall have no liability with respect to the
// infringement of copyrights or patents that any modification to the content
// of this file or this file itself may incur.
//
// ****************************************************************************

#include "stdafx.h"
#include <windows.h>
#include <fstream>
#include "winimage.h"
using namespace std;
// Error processing macro (NO-OP by default):
#define ERRORMSG(PARAM) {}

// ****************************************************************************
// * C_Image Member definitions                                               *
// ****************************************************************************
C_ImageSet::~C_ImageSet(){
		for (int n=0;n<nImages;n++) delete img[n]; delete[] img;
}
void C_ImageSet::Reset()
{
	for (int n=0;n<nImages;n++)
		delete img[n];
	delete[] img;
	img=0;
	nImages=0;
	nLoops=0;
}
// Init: Allocates space for raster and palette in GDI-compatible structures.
void C_Image::Init(int iWidth, int iHeight, int iBPP) {
	if (Raster) {delete[]Raster;Raster=0;}
	if (pbmi) {delete[]pbmi;pbmi=0;}
	// Standard members setup
	Transparent=-1;
	BytesPerRow = Width = iWidth; Height=iHeight; BPP=iBPP;
	// Animation Extra members setup:
	xPos=xPos=Delay=0;

	if (BPP==24)
		{BytesPerRow*=3; pbmi=(BITMAPINFO*)new char [sizeof(BITMAPINFO)];}
	else
	{
		pbmi=(BITMAPINFO*)
			new char[sizeof(BITMAPINFOHEADER)+(1<<BPP)*sizeof(COLOR)];
		Palette=(COLOR*)((char*)pbmi+sizeof(BITMAPINFOHEADER));
	}

	BytesPerRow += (ALIGN-Width%ALIGN) % ALIGN;	// Align BytesPerRow
	
	Raster = new char [BytesPerRow*Height];

	pbmi->bmiHeader.biSize=sizeof (BITMAPINFOHEADER);
	pbmi->bmiHeader.biWidth=Width;
	pbmi->bmiHeader.biHeight=-Height;			// negative means up-to-bottom 
	pbmi->bmiHeader.biPlanes=1;
	pbmi->bmiHeader.biBitCount=(BPP<8?8:BPP);	// Our raster is byte-aligned
	pbmi->bmiHeader.biCompression=BI_RGB;
	pbmi->bmiHeader.biSizeImage=0;
	pbmi->bmiHeader.biXPelsPerMeter=11811;
	pbmi->bmiHeader.biYPelsPerMeter=11811;
	pbmi->bmiHeader.biClrUsed=0;
	pbmi->bmiHeader.biClrImportant=0;
}

// GDIPaint: Paint the raster image onto a DC
int C_Image::GDIPaint (HDC hdc,int x, int y,int iWidth,int iHeight)
{
	return SetDIBitsToDevice (hdc,x,y,iWidth,iHeight,0,0,
								0,Height,(LPVOID)Raster,pbmi,0);
}

// operator=: copies an object's content to another
C_Image& C_Image::operator = (C_Image& rhs)
	{
		Init(rhs.Width,rhs.Height,rhs.BPP);	// respects virtualization
		memcpy (Raster,rhs.Raster,BytesPerRow*Height);
		memcpy ((char*)Palette,(char*)rhs.Palette,(1<<BPP)*sizeof(*Palette));
		return *this;
	}



// ****************************************************************************
// * C_ImageSet Member definitions                                            *
// ****************************************************************************

// AddImage: Adds an image object to the back of the img vector.
void C_ImageSet::AddImage (C_Image* newimage)
{
	C_Image ** pTempImg = new C_Image* [nImages+1];
	int n;
	for (n=0;n<nImages;n++) pTempImg[n]=img[n];	// (pointer copy)
	delete[] img;
	img=pTempImg;
	img[n]=newimage;
	nImages++;
}

// ****************************************************************************
// * FILE FORMAT SUPPORT ROUTINES                                             *
// ****************************************************************************

// ****************************************************************************
// * LoadBMP                                                                  *
// *   Load a BMP File into the C_Image object                                *
// *                        (c) Sept2000, Juan Soulie <jsoulie@cplusplus.com> *
// ****************************************************************************
int C_Image::LoadBMP (char* szFileName)
{
	int n;

	// Open file.
	ifstream bmpfile (szFileName , ios::in | ios::binary | ios::_Nocreate);
	if (! bmpfile.is_open()) { ERRORMSG("File not found"); return 0; }

	// *1* LOAD BITMAP FILE HEADER
	struct BITMAPFILEHEADER {
		unsigned short	bfType; 
		unsigned long	bfSize; 
		unsigned short	bfReserved1; 
		unsigned short	bfReserved2; 
		unsigned long	bfOffBits; 
	} bmfh;
	bmpfile.read ((char*)&bmfh,sizeof (bmfh));

	// Check filetype signature
	if (bmfh.bfType!='MB') { ERRORMSG("Not a valid BMP File"); return 0; }

	// *2* LOAD BITMAP INFO HEADER
	struct BITMAPINFOHEADER {
		unsigned long  biSize;
		         long  biWidth;
		         long  biHeight;
		unsigned short biPlanes;
		unsigned short biBitCount;
		unsigned long  biCompression;
		unsigned long  biSizeImage;
		         long  biXPelsPerMeter;
		         long  biYPelsPerMeter;
		unsigned long  biClrUsed;
		unsigned long  biClrImportant;
	} bmih;
	bmpfile.read ((char*)&bmih,sizeof (bmih));

	// Check for supported Color depths
	if ((bmih.biBitCount!=1) &&
		(bmih.biBitCount!=4) &&
		(bmih.biBitCount!=8) &&
		(bmih.biBitCount!=24))
		{ ERRORMSG("Color depth not supported"); return 0; }

	// Check if file is compressed
	if (bmih.biCompression!=0) 
		{ ERRORMSG("File uses unsupported compression"); return 0; }

	// Set: Allocate memory to contain Data
	Init (bmih.biWidth,
		(bmih.biHeight>0) ? bmih.biHeight: -bmih.biHeight,	// abs
		bmih.biBitCount);

	// *3* IF BPP AREN'T 24, LOAD PALETTE.
	if (BPP!=24)
	{
		for (n=0;n< 1<<BPP;n++)
		{
			Palette[n].b=bmpfile.get();
			Palette[n].g=bmpfile.get();
			Palette[n].r=bmpfile.get();
			bmpfile.get();	// 4th byte of RGBQUAD discarded
		}
	}

	// *4* LOAD RASTER DATA

	// Seek Raster Data in file
	bmpfile.seekg (bmfh.bfOffBits,ios::beg);

	int PixelsPerByte = 8/BPP;	//used only if BPP are less than 8
	int BitMask = (1<<BPP)-1;	//used only if BPP are less than 8

	// Raster Data Rows are 32bit aligned in BMP files.
	int RowAlignmentInFile = ((4- ((Width*BPP+7)/8)%4)%4); // (bytes)

	for (int row=0; row<Height; row++)
	{
		char * pPixel;
		// If height is positive the bmp is bottom-up, set adequate row info:
		pPixel= Raster + BytesPerRow *
			( (bmih.biHeight>0)? Height-row-1 : row );

		if (BPP >= 8)	// 8 or more BPP: Read as block.
			bmpfile.read (pPixel, Width*BPP/8);

		else				// Less than 8BPP: Read and store byte aligned.
		{
			int charGot;
			for (int col=0; col < Width; col+=PixelsPerByte)
			{
				charGot=bmpfile.get();
				for (int bit=8 ; bit >0 ; bit -= BPP)	// high to low
					*pPixel++ = (charGot>> (bit - BPP)) & BitMask;
			}
		}
		// Ignore aligment bytes of file:
		for (int m=0; m<RowAlignmentInFile; m++) bmpfile.get ();
	}

	bmpfile.close();
	return 1;
}


// ****************************************************************************
// * SaveBMP                                                                  *
// *   Save the content of a C_Image object into a BMP file                   *
// *                        (c) Sept2000, Juan Soulie <jsoulie@cplusplus.com> *
// ****************************************************************************
int C_Image::SaveBMP (char * szFileName)
{
	int n;

	// Create file.
	ofstream bmpfile (szFileName , ios::out | ios::binary | ios::trunc);
	if (! bmpfile.is_open()) { ERRORMSG("Error creating file"); return 0;}

	// determine BPP for file:
	int SaveBPP;
	if (BPP == 1) SaveBPP=1;
	else if (BPP <= 4) SaveBPP=4;
	else if (BPP <= 8) SaveBPP=8;
	else SaveBPP=24;

	// *1* SAVE BITMAP FILE HEADER
	struct BITMAPFILEHEADER {
		unsigned short	bfType; 
		unsigned long	bfSize; 
		unsigned short	bfReserved1; 
		unsigned short	bfReserved2; 
		unsigned long	bfOffBits; 
	} bmfh;

	bmfh.bfType='MB';
	bmfh.bfSize=0;	// TO DO
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
	bmfh.bfOffBits = 54 + ((SaveBPP==24) ? 0 : (1<<SaveBPP)*4);
	bmpfile.write ((char*)&bmfh,sizeof (bmfh));

	// *2* SAVE BITMAP INFO HEADER
	struct BITMAPINFOHEADER {
		unsigned long  biSize;
		         long  biWidth;
		         long  biHeight;
		unsigned short biPlanes;
		unsigned short biBitCount;
		unsigned long  biCompression;
		unsigned long  biSizeImage;
		         long  biXPelsPerMeter;
		         long  biYPelsPerMeter;
		unsigned long  biClrUsed;
		unsigned long  biClrImportant;
	} bmih;

	bmih.biSize=sizeof(bmih);
	bmih.biWidth=Width;
	bmih.biHeight=Height;	// down-top
	bmih.biPlanes=1;
	bmih.biBitCount=SaveBPP;
	bmih.biCompression=0;// BI_RGB?
	bmih.biSizeImage =(Width*BPP)/8;
	bmih.biSizeImage += (4- (bmih.biSizeImage)%4)%4;
	bmih.biXPelsPerMeter=11811;
	bmih.biYPelsPerMeter=11811;
	bmih.biClrUsed=0;
	bmih.biClrImportant=0;

	bmpfile.write ((char*)&bmih,sizeof (bmih));

	// *3* IF BPP AREN'T 24, SAVE PALETTE.
	if (BPP!=24)
	{
		for (n=0;n< 1<<BPP;n++)
		{
			bmpfile.put(Palette[n].b);
			bmpfile.put(Palette[n].g);
			bmpfile.put(Palette[n].r);
			bmpfile.put((char)0);
		}
		for (;n < 1<<SaveBPP; n++)	// in case SaveBPP is higher than BPP
			bmpfile.write((char*)'\0\0\0\0',4);
	}

	// *4* SAVE RASTER DATA

	int PixelsPerByte = 8/SaveBPP;	//used only if BPP are less than 8
	int BitMask = (1<<SaveBPP)-1;	//used only if BPP are less than 8

	// Raster Data Rows are 32bit aligned in BMP files.
	int RowAlignmentInFile = ((4- ((Width*SaveBPP+7)/8)%4)%4); // (bytes)
	for (int row=0; row<Height; row++)
	{
		char * pPixel;
		// If height is positive the bmp is bottom-up, set adequate row info:
		pPixel= (char*) Raster + BytesPerRow *
			( (bmih.biHeight>0)? Height-row-1 : row );

		if (SaveBPP >= 8)	// 8 or more BPP: Save as block.
			bmpfile.write (pPixel, Width*SaveBPP/8);

		else				// Less than 8BPP: Save packing bytes.
		{
			unsigned char charToPut;
			for (int col=0; col < Width; col+=PixelsPerByte)
			{
				charToPut=0;
				for (int bit=8 ; bit >0 ; bit -= BPP)	// high to low
					charToPut |= (*pPixel++ & BitMask) << (bit - BPP);
				bmpfile.put(charToPut);
			}
		}
		// Ignore aligment bytes of file:
		for (int m=0; m<RowAlignmentInFile; m++) bmpfile.put ((char)0);
	}


	bmpfile.close();
	return 1;

}

// pre-declaration:
int LZWDecoder (char*, char*, short, int, int, int, const int);

// ****************************************************************************
// * LoadGIF                                                                  *
// *   Load a GIF File into the C_ImageSet object                             *
// *                        (c) Nov 2000, Juan Soulie <jsoulie@cplusplus.com> *
// ****************************************************************************
int C_ImageSet::LoadGIF (char * szFileName)
{
	int n, nPage;

	// Global GIF variables:
	int GlobalBPP;						// Bits per Pixel.
	COLOR * GlobalColorMap;				// Global colormap (allocate)

	struct GIFGCEtag {				// GRAPHIC CONTROL EXTENSION
		unsigned char BlockSize;		// Block Size: 4 bytes
		unsigned char PackedFields;		// Packed Fields. Bits detail:
										//    0: Transparent Color Flag
										//    1: User Input Flag
										//  2-4: Disposal Method

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -