1. 최초 커밋
This commit is contained in:
371
.gitignore
vendored
Normal file
371
.gitignore
vendored
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/visualstudio
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio
|
||||||
|
|
||||||
|
### VisualStudio ###
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*[.json, .xml, .info]
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
### VisualStudio Patch ###
|
||||||
|
# Additional files built by Visual Studio
|
||||||
|
*.tlog
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/visualstudio
|
||||||
20
Raw2Bmp_MFC.sln
Normal file
20
Raw2Bmp_MFC.sln
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
|
# Visual Studio 2010
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raw2Bmp_MFC", "Raw2Bmp_MFC\Raw2Bmp_MFC.vcxproj", "{C2BB4747-AA19-43FF-9484-FCBE8004EB82}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C2BB4747-AA19-43FF-9484-FCBE8004EB82}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{C2BB4747-AA19-43FF-9484-FCBE8004EB82}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{C2BB4747-AA19-43FF-9484-FCBE8004EB82}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{C2BB4747-AA19-43FF-9484-FCBE8004EB82}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
BIN
Raw2Bmp_MFC/1.DX
Normal file
BIN
Raw2Bmp_MFC/1.DX
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/1.png
Normal file
BIN
Raw2Bmp_MFC/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 MiB |
BIN
Raw2Bmp_MFC/1.raw
Normal file
BIN
Raw2Bmp_MFC/1.raw
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/CONSOL.png
Normal file
BIN
Raw2Bmp_MFC/CONSOL.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 MiB |
BIN
Raw2Bmp_MFC/CONSOL.raw
Normal file
BIN
Raw2Bmp_MFC/CONSOL.raw
Normal file
Binary file not shown.
301
Raw2Bmp_MFC/ImageUtility.cpp
Normal file
301
Raw2Bmp_MFC/ImageUtility.cpp
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
#include "ImageUtility.h"
|
||||||
|
|
||||||
|
HINTERNET g_hOpen, g_hConnect;
|
||||||
|
|
||||||
|
/////////////////// WorkerFunction //////////////////////
|
||||||
|
DWORD WINAPI WorkerFunction(IN LPVOID vThreadParm)
|
||||||
|
/*
|
||||||
|
Purpose:
|
||||||
|
Call InternetConnect to establish a FTP session
|
||||||
|
Arguments:
|
||||||
|
vThreadParm - points to PARM passed to thread
|
||||||
|
Returns:
|
||||||
|
returns 0
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
//PARM* pThreadParm;
|
||||||
|
// Initialize local pointer to void pointer passed to thread
|
||||||
|
//pThreadParm = (PARM*)vThreadParm;
|
||||||
|
|
||||||
|
FTP_INFO *ftpinfo = (FTP_INFO*)vThreadParm;
|
||||||
|
|
||||||
|
if (ftpinfo == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
g_hConnect = 0;
|
||||||
|
|
||||||
|
if ( !( g_hConnect = InternetConnect (
|
||||||
|
g_hOpen,
|
||||||
|
ftpinfo->ConnectAddress,
|
||||||
|
ftpinfo->ConnectPort,
|
||||||
|
ftpinfo->Id,
|
||||||
|
ftpinfo->Pw,
|
||||||
|
INTERNET_SERVICE_FTP,
|
||||||
|
INTERNET_FLAG_PASSIVE,
|
||||||
|
0 ) ) )
|
||||||
|
{
|
||||||
|
//cerr << "Error on InternetConnnect: " << GetLastError() << endl;
|
||||||
|
|
||||||
|
return 1; // failure
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // success
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageUtility::CImageUtility(void) : pFtpUploadThread(NULL), pFtpUploadThread_ing(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CImageUtility::~CImageUtility(void)
|
||||||
|
{
|
||||||
|
if (pFtpUploadThread_ing)
|
||||||
|
{
|
||||||
|
if (WaitForSingleObject (pFtpUploadThread_ing->m_hThread, 2000) == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
AfxMessageBox(_T("Current File Upload Cancel"), MB_OK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CImageUtility::FileRead(CString FilePath, uint32_t Width, uint32_t Height, void *mem, uint32_t TypeSize)
|
||||||
|
{
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
int errorno = 0;
|
||||||
|
int FileLen = Width * Height;
|
||||||
|
if((errorno = fopen_s(&fp,FilePath,"rb")))
|
||||||
|
{
|
||||||
|
AfxMessageBox("Read File Open Error 00");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fseek(fp,0L,SEEK_END);
|
||||||
|
long len =ftell(fp);
|
||||||
|
fseek(fp, len-FileLen*TypeSize, SEEK_SET);
|
||||||
|
int ReadCount = fread(mem,TypeSize,FileLen,fp);
|
||||||
|
if(ReadCount < FileLen)
|
||||||
|
{
|
||||||
|
AfxMessageBox("File Read error 00!");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT CImageUtility::FileRead_Thread ( LPVOID pParam )
|
||||||
|
{
|
||||||
|
FTP_INFO *ftpinfo = (FTP_INFO*)pParam;
|
||||||
|
|
||||||
|
if (ftpinfo == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( g_hConnect == NULL ) return 0;
|
||||||
|
|
||||||
|
if( !FtpSetCurrentDirectory( g_hConnect, ftpinfo->DirPath ) )
|
||||||
|
{
|
||||||
|
AfxMessageBox(_T("FTP Path Error"));
|
||||||
|
|
||||||
|
InternetCloseHandle( g_hConnect );
|
||||||
|
InternetCloseHandle( g_hOpen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !FtpPutFile( g_hConnect, ftpinfo->UploadFile, ftpinfo->UploadFile, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_RELOAD, 0 ))
|
||||||
|
{
|
||||||
|
AfxMessageBox(_T("FTP File Put Error"));
|
||||||
|
|
||||||
|
InternetCloseHandle( g_hConnect );
|
||||||
|
InternetCloseHandle( g_hOpen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageUtility::FileUpload (FTP_INFO *ftpinfo)
|
||||||
|
{
|
||||||
|
if (ftpinfo == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CONNECT_RETRY:
|
||||||
|
|
||||||
|
BOOL bRetry = FALSE;
|
||||||
|
|
||||||
|
// FTP <20><><EFBFBD><EFBFBD>
|
||||||
|
if( (g_hOpen = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL)) == NULL )
|
||||||
|
{
|
||||||
|
DWORD dwgle = GetLastError();
|
||||||
|
CString strTempory;
|
||||||
|
strTempory.Format(_T("Can't Use Network, Windows Code : 0x%08X"), dwgle);
|
||||||
|
AfxMessageBox(strTempory);
|
||||||
|
SAFE_DELETE(ftpinfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FTP <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
pFtpUploadThread = AfxBeginThread( (AFX_THREADPROC)WorkerFunction, ftpinfo, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
|
||||||
|
pFtpUploadThread->m_bAutoDelete = FALSE;
|
||||||
|
pFtpUploadThread->ResumeThread();
|
||||||
|
|
||||||
|
if (!pFtpUploadThread)
|
||||||
|
{
|
||||||
|
AfxMessageBox(_T("Windows Thread Fail"));
|
||||||
|
SAFE_DELETE(ftpinfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD dwResult = WaitForSingleObject (pFtpUploadThread->m_hThread, 5000);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<>Ӿƿ<D3BE> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||||
|
if (dwResult == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
if ( g_hOpen )
|
||||||
|
{
|
||||||
|
InternetCloseHandle ( g_hOpen );
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>尡 TimeOut<75><74> <20><>Ȳ<EFBFBD><C8B2> InternetCloseHandle<6C>μ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
WaitForSingleObject (pFtpUploadThread->m_hThread, INFINITE);
|
||||||
|
|
||||||
|
bRetry = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD> (<28><><EFBFBD><EFBFBD> <20>Ұ<EFBFBD>)
|
||||||
|
if (dwResult == WAIT_OBJECT_0 && !g_hConnect)
|
||||||
|
{
|
||||||
|
if ( g_hOpen )
|
||||||
|
{
|
||||||
|
InternetCloseHandle ( g_hOpen );
|
||||||
|
}
|
||||||
|
|
||||||
|
bRetry = TRUE;
|
||||||
|
}
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD> (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||||
|
else if (dwResult == WAIT_OBJECT_0 && g_hConnect)
|
||||||
|
{
|
||||||
|
bRetry = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pFtpUploadThread;
|
||||||
|
pFtpUploadThread = NULL;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD> Ȯ<><C8AE>
|
||||||
|
if (bRetry)
|
||||||
|
{
|
||||||
|
if (ftpinfo->CheckConnect)
|
||||||
|
{
|
||||||
|
SAFE_DELETE(ftpinfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AfxMessageBox(_T("FTP Connect Fail, Retry?"), MB_RETRYCANCEL) == IDRETRY)
|
||||||
|
{
|
||||||
|
goto CONNECT_RETRY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SAFE_DELETE(ftpinfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FTP <20><><EFBFBD>ε<EFBFBD>
|
||||||
|
|
||||||
|
pFtpUploadThread_ing = AfxBeginThread( (AFX_THREADPROC)FileRead_Thread, ftpinfo, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
|
||||||
|
pFtpUploadThread_ing->m_bAutoDelete = FALSE;
|
||||||
|
pFtpUploadThread_ing->ResumeThread();
|
||||||
|
|
||||||
|
if (pFtpUploadThread_ing)
|
||||||
|
{
|
||||||
|
DWORD dwResult = WaitForSingleObject (pFtpUploadThread_ing->m_hThread, 30000);
|
||||||
|
|
||||||
|
if (dwResult == WAIT_TIMEOUT)
|
||||||
|
AfxMessageBox(_T("Image Upload TimeOut (max 30sec)"));
|
||||||
|
|
||||||
|
delete pFtpUploadThread_ing;
|
||||||
|
pFtpUploadThread_ing = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( g_hOpen )
|
||||||
|
{
|
||||||
|
InternetCloseHandle( g_hOpen );
|
||||||
|
g_hOpen = NULL;
|
||||||
|
}
|
||||||
|
if( g_hConnect )
|
||||||
|
{
|
||||||
|
InternetCloseHandle( g_hConnect );
|
||||||
|
g_hConnect = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SAFE_DELETE(ftpinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CImageUtility::MakeImage (CString strRawFilePath, CString strOutFilePath, uint32_t Width, uint32_t Height, UINT Type/* = 14*/)
|
||||||
|
{
|
||||||
|
CxImage img;
|
||||||
|
|
||||||
|
// RAW <20><EFBFBD><DEB8><EFBFBD> <20>ε<EFBFBD>
|
||||||
|
BYTE *pRaw = new BYTE[Width*Height*2];
|
||||||
|
if (!FileRead(strRawFilePath,Width, Height,pRaw,sizeof(WORD)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
WORD nMin = 0xFFFF;
|
||||||
|
WORD nMax = 0;
|
||||||
|
WORD nTemp;
|
||||||
|
double dTemp;
|
||||||
|
|
||||||
|
// min, max Ž<><C5BD>
|
||||||
|
WORD *pWord = (WORD *)pRaw;
|
||||||
|
for (UINT i=0; i<Width*Height; i++)
|
||||||
|
{
|
||||||
|
// 2Byte <20><><EFBFBD><EFBFBD>
|
||||||
|
nTemp = pWord[i] >> (16 - Type);
|
||||||
|
|
||||||
|
if( nTemp > nMax )
|
||||||
|
nMax = nTemp;
|
||||||
|
if( nTemp < nMin )
|
||||||
|
nMin = nTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// min, max<61><78> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||||
|
for (UINT i=0; i<Width*Height; i++)
|
||||||
|
{
|
||||||
|
// 2Byte <20><><EFBFBD><EFBFBD>
|
||||||
|
nTemp = pWord[i] >> (16 - Type);
|
||||||
|
|
||||||
|
dTemp = (((double)nTemp - (double)nMin) / ((double)nMax - (double)nMin)) * 0xFF /*8bit*/;
|
||||||
|
|
||||||
|
pWord[i] = (WORD)dTemp;
|
||||||
|
//pRaw[i] = (BYTE)pWord[i];
|
||||||
|
pRaw[i] = (BYTE)pWord[i] * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!img.CreateFromArray(pRaw, Width, Height, 8, Width, TRUE))
|
||||||
|
{
|
||||||
|
delete [] pRaw;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!img.Save(strOutFilePath, CXIMAGE_FORMAT_PNG))
|
||||||
|
{
|
||||||
|
delete [] pRaw;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] pRaw;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageUtility::ResizeImage (CString strFilePath, uint32_t Width, uint32_t Height)
|
||||||
|
{
|
||||||
|
CxImage img;
|
||||||
|
|
||||||
|
img.Load(strFilePath);
|
||||||
|
img.Resample(Width, Width);
|
||||||
|
img.Save(strFilePath, CXIMAGE_FORMAT_PNG);
|
||||||
|
}
|
||||||
77
Raw2Bmp_MFC/ImageUtility.h
Normal file
77
Raw2Bmp_MFC/ImageUtility.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <wininet.h>
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
/*
|
||||||
|
//CString raw = _T("./1.raw");
|
||||||
|
//CString dst = _T("./1.png");
|
||||||
|
|
||||||
|
//CImageUtility IU;
|
||||||
|
//IU.MakeImage(raw, dst, 2520, 3032); default 14 bit
|
||||||
|
//IU.MakeImage(raw, dst, 3072, 3072, 14);
|
||||||
|
//IU.MakeImage(raw, dst, 2520, 3032, 16);
|
||||||
|
|
||||||
|
//IU.ResizeImage (dst, 480, 480);
|
||||||
|
|
||||||
|
//FTP_INFO *FI = new FTP_INFO;
|
||||||
|
//FI->ConnectAddress = _T("192.168.51.5");
|
||||||
|
//FI->ConnectPort = 21;
|
||||||
|
//FI->Id = _T("-----");
|
||||||
|
//FI->Pw = _T("-----");
|
||||||
|
//FI->DirPath = _T("/<2F><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD><EEBFAC><EFBFBD><EFBFBD>tmp");
|
||||||
|
//FI->UploadFile = dst;
|
||||||
|
|
||||||
|
//IU.FileUpload ( FI );
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SAFE_DELETE(x) if (ftpinfo) delete ftpinfo; ftpinfo = NULL;
|
||||||
|
|
||||||
|
DWORD WINAPI WorkerFunction( LPVOID );
|
||||||
|
|
||||||
|
typedef struct _FTP_INFO
|
||||||
|
{
|
||||||
|
CString ConnectAddress;
|
||||||
|
INTERNET_PORT ConnectPort;
|
||||||
|
CString DirPath;
|
||||||
|
CString Id;
|
||||||
|
CString Pw;
|
||||||
|
CString UploadFile;
|
||||||
|
BOOL CheckConnect;
|
||||||
|
|
||||||
|
_FTP_INFO (BOOL bCheckConnect = FALSE)
|
||||||
|
{
|
||||||
|
CheckConnect = bCheckConnect;
|
||||||
|
};
|
||||||
|
|
||||||
|
}FTP_INFO;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
CHAR* pHost;
|
||||||
|
CHAR* pUser;
|
||||||
|
CHAR* pPass;
|
||||||
|
} PARM;
|
||||||
|
|
||||||
|
class CImageUtility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CImageUtility(void);
|
||||||
|
virtual ~CImageUtility(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BOOL FileRead (CString FilePath, uint32_t Width, uint32_t Height, void *mem, uint32_t TypeSize);
|
||||||
|
|
||||||
|
// ThreadFnc
|
||||||
|
CWinThread *pFtpUploadThread;
|
||||||
|
CWinThread *pFtpUploadThread_ing;
|
||||||
|
|
||||||
|
static UINT FileRead_Thread ( LPVOID pParam );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
public:
|
||||||
|
|
||||||
|
BOOL MakeImage (CString strRawFilePath, CString strOutFilePath, uint32_t Width, uint32_t Height, UINT Type = 14);
|
||||||
|
void ResizeImage (CString strFilePath, uint32_t Width, uint32_t Height);
|
||||||
|
void FileUpload (FTP_INFO *ftpinfo);
|
||||||
|
};
|
||||||
100
Raw2Bmp_MFC/Raw2Bmp_MFC.cpp
Normal file
100
Raw2Bmp_MFC/Raw2Bmp_MFC.cpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
// Raw2Bmp_MFC.cpp : <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "Raw2Bmp_MFC.h"
|
||||||
|
#include "Raw2Bmp_MFCDlg.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCApp
|
||||||
|
|
||||||
|
BEGIN_MESSAGE_MAP(CRaw2Bmp_MFCApp, CWinApp)
|
||||||
|
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
|
||||||
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCApp <20><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
CRaw2Bmp_MFCApp::CRaw2Bmp_MFCApp()
|
||||||
|
{
|
||||||
|
// <20>ٽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
|
||||||
|
|
||||||
|
// TODO: <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڵ带 <20>߰<EFBFBD><DFB0>մϴ<D5B4>.
|
||||||
|
// InitInstance<63><65> <20><><EFBFBD><EFBFBD> <20>߿<EFBFBD><DFBF><EFBFBD> <20>ʱ<EFBFBD>ȭ <20>۾<EFBFBD><DBBE><EFBFBD> <20><>ġ<EFBFBD>մϴ<D5B4>.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CRaw2Bmp_MFCApp <20><>ü<EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
CRaw2Bmp_MFCApp theApp;
|
||||||
|
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCApp <20>ʱ<EFBFBD>ȭ
|
||||||
|
|
||||||
|
BOOL CRaw2Bmp_MFCApp::InitInstance()
|
||||||
|
{
|
||||||
|
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20>Ŵ<EFBFBD><C5B4>佺Ʈ<E4BDBA><C6AE> ComCtl32.dll <20><><EFBFBD><EFBFBD> 6 <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD>־<EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD>
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>, Windows XP <20><EFBFBD> <20>ݵ<EFBFBD><DDB5><EFBFBD> InitCommonControlsEx()<29><> <20>ʿ<EFBFBD><CABF>մϴ<D5B4>.
|
||||||
|
// InitCommonControlsEx()<29><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> â<><C3A2> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
||||||
|
INITCOMMONCONTROLSEX InitCtrls;
|
||||||
|
InitCtrls.dwSize = sizeof(InitCtrls);
|
||||||
|
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>
|
||||||
|
// <20><> <20><EFBFBD><D7B8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻʽÿ<CABD>.
|
||||||
|
InitCtrls.dwICC = ICC_WIN95_CLASSES;
|
||||||
|
InitCommonControlsEx(&InitCtrls);
|
||||||
|
|
||||||
|
CWinApp::InitInstance();
|
||||||
|
|
||||||
|
if (!AfxSocketInit())
|
||||||
|
{
|
||||||
|
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AfxEnableControlContainer();
|
||||||
|
|
||||||
|
// <20><>ȭ <20><><EFBFBD>ڿ<EFBFBD> <20><> Ʈ<><C6AE> <20><> <20>Ǵ<EFBFBD>
|
||||||
|
// <20><> <20><><EFBFBD><EFBFBD> <20><> <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǾ<D4B5> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
||||||
|
CShellManager *pShellManager = new CShellManager;
|
||||||
|
|
||||||
|
// ǥ<><C7A5> <20>ʱ<EFBFBD>ȭ
|
||||||
|
// <20>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ũ<>⸦ <20><><EFBFBD>̷<EFBFBD><CCB7><EFBFBD>
|
||||||
|
// <20>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> Ư<><C6AF> <20>ʱ<EFBFBD>ȭ
|
||||||
|
// <20><>ƾ<EFBFBD><C6BE> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>մϴ<D5B4>.
|
||||||
|
// <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> Ű<><C5B0> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻʽÿ<CABD>.
|
||||||
|
// TODO: <20><> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> ȸ<><C8B8> <20>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>մϴ<D5B4>.
|
||||||
|
SetRegistryKey(_T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>翡<EFBFBD><E7BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1>"));
|
||||||
|
|
||||||
|
CRaw2Bmp_MFCDlg dlg;
|
||||||
|
m_pMainWnd = &dlg;
|
||||||
|
INT_PTR nResponse = dlg.DoModal();
|
||||||
|
if (nResponse == IDOK)
|
||||||
|
{
|
||||||
|
// TODO: <20><><EFBFBD> [Ȯ<><C8AE>]<5D><> Ŭ<><C5AC><EFBFBD>Ͽ<EFBFBD> <20><>ȭ <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> ó<><C3B3><EFBFBD><EFBFBD>
|
||||||
|
// <20>ڵ带 <20><>ġ<EFBFBD>մϴ<D5B4>.
|
||||||
|
}
|
||||||
|
else if (nResponse == IDCANCEL)
|
||||||
|
{
|
||||||
|
// TODO: <20><><EFBFBD> [<5B><><EFBFBD><EFBFBD>]<5D><> Ŭ<><C5AC><EFBFBD>Ͽ<EFBFBD> <20><>ȭ <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> ó<><C3B3><EFBFBD><EFBFBD>
|
||||||
|
// <20>ڵ带 <20><>ġ<EFBFBD>մϴ<D5B4>.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
if (pShellManager != NULL)
|
||||||
|
{
|
||||||
|
delete pShellManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ȭ <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><EFBFBD><DEBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ֵ<EFBFBD><D6B5><EFBFBD> FALSE<53><45>
|
||||||
|
// <20><>ȯ<EFBFBD>մϴ<D5B4>.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
32
Raw2Bmp_MFC/Raw2Bmp_MFC.h
Normal file
32
Raw2Bmp_MFC/Raw2Bmp_MFC.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
// Raw2Bmp_MFC.h : PROJECT_NAME <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __AFXWIN_H__
|
||||||
|
#error "PCH<43><48> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> 'stdafx.h'<27><> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "resource.h" // <20><> <20><>ȣ<EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCApp:
|
||||||
|
// <20><> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> Raw2Bmp_MFC.cpp<70><70> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻʽÿ<CABD>.
|
||||||
|
//
|
||||||
|
|
||||||
|
class CRaw2Bmp_MFCApp : public CWinApp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CRaw2Bmp_MFCApp();
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
public:
|
||||||
|
virtual BOOL InitInstance();
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
DECLARE_MESSAGE_MAP()
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CRaw2Bmp_MFCApp theApp;
|
||||||
BIN
Raw2Bmp_MFC/Raw2Bmp_MFC.rc
Normal file
BIN
Raw2Bmp_MFC/Raw2Bmp_MFC.rc
Normal file
Binary file not shown.
164
Raw2Bmp_MFC/Raw2Bmp_MFC.vcxproj
Normal file
164
Raw2Bmp_MFC/Raw2Bmp_MFC.vcxproj
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{C2BB4747-AA19-43FF-9484-FCBE8004EB82}</ProjectGuid>
|
||||||
|
<RootNamespace>Raw2Bmp_MFC</RootNamespace>
|
||||||
|
<Keyword>MFCProj</Keyword>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<UseOfMfc>Dynamic</UseOfMfc>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)include</AdditionalIncludeDirectories>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(ProjectDir)include</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>
|
||||||
|
</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<Midl>
|
||||||
|
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||||
|
<ValidateAllParameters>true</ValidateAllParameters>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</Midl>
|
||||||
|
<ResourceCompile>
|
||||||
|
<Culture>0x0412</Culture>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalLibraryDirectories>$(ProjectDir)include</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<Midl>
|
||||||
|
<MkTypLibCompatible>false</MkTypLibCompatible>
|
||||||
|
<ValidateAllParameters>true</ValidateAllParameters>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</Midl>
|
||||||
|
<ResourceCompile>
|
||||||
|
<Culture>0x0412</Culture>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="ReadMe.txt" />
|
||||||
|
<None Include="res\Raw2Bmp_MFC.ico" />
|
||||||
|
<None Include="res\Raw2Bmp_MFC.rc2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ImageUtility.h" />
|
||||||
|
<ClInclude Include="include\stdint.h" />
|
||||||
|
<ClInclude Include="include\xfile.h" />
|
||||||
|
<ClInclude Include="include\ximabmp.h" />
|
||||||
|
<ClInclude Include="include\ximacfg.h" />
|
||||||
|
<ClInclude Include="include\ximadef.h" />
|
||||||
|
<ClInclude Include="include\ximage.h" />
|
||||||
|
<ClInclude Include="include\ximagif.h" />
|
||||||
|
<ClInclude Include="include\ximaico.h" />
|
||||||
|
<ClInclude Include="include\ximaiter.h" />
|
||||||
|
<ClInclude Include="include\ximajas.h" />
|
||||||
|
<ClInclude Include="include\ximajbg.h" />
|
||||||
|
<ClInclude Include="include\ximajpg.h" />
|
||||||
|
<ClInclude Include="include\ximamng.h" />
|
||||||
|
<ClInclude Include="include\ximapcx.h" />
|
||||||
|
<ClInclude Include="include\ximapng.h" />
|
||||||
|
<ClInclude Include="include\ximapsd.h" />
|
||||||
|
<ClInclude Include="include\ximaraw.h" />
|
||||||
|
<ClInclude Include="include\ximaska.h" />
|
||||||
|
<ClInclude Include="include\ximatga.h" />
|
||||||
|
<ClInclude Include="include\ximath.h" />
|
||||||
|
<ClInclude Include="include\ximatif.h" />
|
||||||
|
<ClInclude Include="include\ximawbmp.h" />
|
||||||
|
<ClInclude Include="include\ximawmf.h" />
|
||||||
|
<ClInclude Include="include\xiofile.h" />
|
||||||
|
<ClInclude Include="include\xmemfile.h" />
|
||||||
|
<ClInclude Include="Raw2Bmp_MFC.h" />
|
||||||
|
<ClInclude Include="Raw2Bmp_MFCDlg.h" />
|
||||||
|
<ClInclude Include="Resource.h" />
|
||||||
|
<ClInclude Include="stdafx.h" />
|
||||||
|
<ClInclude Include="targetver.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ImageUtility.cpp" />
|
||||||
|
<ClCompile Include="Raw2Bmp_MFC.cpp" />
|
||||||
|
<ClCompile Include="Raw2Bmp_MFCDlg.cpp" />
|
||||||
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="Raw2Bmp_MFC.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<UserProperties RESOURCE_FILE="Raw2Bmp_MFC.rc" />
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
</Project>
|
||||||
143
Raw2Bmp_MFC/Raw2Bmp_MFC.vcxproj.filters
Normal file
143
Raw2Bmp_MFC/Raw2Bmp_MFC.vcxproj.filters
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="소스 파일">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="헤더 파일">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="리소스 파일">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="ximage">
|
||||||
|
<UniqueIdentifier>{0e9eada1-a1fb-4757-9922-164453846424}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="ReadMe.txt" />
|
||||||
|
<None Include="res\Raw2Bmp_MFC.rc2">
|
||||||
|
<Filter>리소스 파일</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="res\Raw2Bmp_MFC.ico">
|
||||||
|
<Filter>리소스 파일</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Raw2Bmp_MFC.h">
|
||||||
|
<Filter>헤더 파일</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Raw2Bmp_MFCDlg.h">
|
||||||
|
<Filter>헤더 파일</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="stdafx.h">
|
||||||
|
<Filter>헤더 파일</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="targetver.h">
|
||||||
|
<Filter>헤더 파일</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Resource.h">
|
||||||
|
<Filter>헤더 파일</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximatif.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximawbmp.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximawmf.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\xiofile.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\xmemfile.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\stdint.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\xfile.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximabmp.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximacfg.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximadef.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximage.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximagif.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximaico.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximaiter.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximajas.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximajbg.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximajpg.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximamng.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximapcx.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximapng.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximapsd.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximaraw.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximaska.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximatga.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ximath.h">
|
||||||
|
<Filter>ximage</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageUtility.h">
|
||||||
|
<Filter>헤더 파일</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Raw2Bmp_MFC.cpp">
|
||||||
|
<Filter>소스 파일</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Raw2Bmp_MFCDlg.cpp">
|
||||||
|
<Filter>소스 파일</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
<Filter>소스 파일</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageUtility.cpp">
|
||||||
|
<Filter>소스 파일</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="Raw2Bmp_MFC.rc">
|
||||||
|
<Filter>리소스 파일</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
118
Raw2Bmp_MFC/Raw2Bmp_MFCDlg.cpp
Normal file
118
Raw2Bmp_MFC/Raw2Bmp_MFCDlg.cpp
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
|
||||||
|
// Raw2Bmp_MFCDlg.cpp : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "Raw2Bmp_MFC.h"
|
||||||
|
#include "Raw2Bmp_MFCDlg.h"
|
||||||
|
#include "afxdialogex.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define new DEBUG_NEW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCDlg <20><>ȭ <20><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
#define RAW_WIDTH 3072
|
||||||
|
#define RAW_HEIGHT 3072
|
||||||
|
|
||||||
|
CRaw2Bmp_MFCDlg::CRaw2Bmp_MFCDlg(CWnd* pParent /*=NULL*/)
|
||||||
|
: CDialogEx(CRaw2Bmp_MFCDlg::IDD, pParent)
|
||||||
|
{
|
||||||
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRaw2Bmp_MFCDlg::DoDataExchange(CDataExchange* pDX)
|
||||||
|
{
|
||||||
|
CDialogEx::DoDataExchange(pDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_MESSAGE_MAP(CRaw2Bmp_MFCDlg, CDialogEx)
|
||||||
|
ON_WM_PAINT()
|
||||||
|
ON_WM_QUERYDRAGICON()
|
||||||
|
ON_BN_CLICKED(IDOK, &CRaw2Bmp_MFCDlg::OnBnClickedOk)
|
||||||
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCDlg <20><EFBFBD><DEBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
BOOL CRaw2Bmp_MFCDlg::OnInitDialog()
|
||||||
|
{
|
||||||
|
CDialogEx::OnInitDialog();
|
||||||
|
|
||||||
|
// <20><> <20><>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><> â<><C3A2> <20><>ȭ <20><><EFBFBD>ڰ<EFBFBD> <20>ƴ<EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1>
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>ũ<EFBFBD><C5A9> <20><> <20>۾<EFBFBD><DBBE><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
SetIcon(m_hIcon, TRUE); // ū <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
SetIcon(m_hIcon, FALSE); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
// TODO: <20><><EFBFBD> <20>߰<EFBFBD> <20>ʱ<EFBFBD>ȭ <20>۾<EFBFBD><DBBE><EFBFBD> <20>߰<EFBFBD><DFB0>մϴ<D5B4>.
|
||||||
|
|
||||||
|
return TRUE; // <20><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD>ѿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TRUE<55><45> <20><>ȯ<EFBFBD>մϴ<D5B4>.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><>ȭ <20><><EFBFBD>ڿ<EFBFBD> <20>ּ<EFBFBD>ȭ <20><><EFBFBD>߸<EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><D7B8><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// <20>Ʒ<EFBFBD> <20>ڵ尡 <20>ʿ<EFBFBD><CABF>մϴ<D5B4>. <20><><EFBFBD><EFBFBD>/<2F><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> MFC <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1>
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>ũ<EFBFBD><C5A9><EFBFBD><EFBFBD> <20><> <20>۾<EFBFBD><DBBE><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
void CRaw2Bmp_MFCDlg::OnPaint()
|
||||||
|
{
|
||||||
|
if (IsIconic())
|
||||||
|
{
|
||||||
|
CPaintDC dc(this); // <20><EFBFBD><D7B8>⸦ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD>ؽ<EFBFBD>Ʈ<EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
||||||
|
|
||||||
|
// Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ <20>簢<EFBFBD><E7B0A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EEB5A5> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
||||||
|
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||||||
|
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||||||
|
CRect rect;
|
||||||
|
GetClientRect(&rect);
|
||||||
|
int x = (rect.Width() - cxIcon + 1) / 2;
|
||||||
|
int y = (rect.Height() - cyIcon + 1) / 2;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><D7B8>ϴ<EFBFBD>.
|
||||||
|
dc.DrawIcon(x, y, m_hIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CDialogEx::OnPaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20>ּ<EFBFBD>ȭ<EFBFBD><C8AD> â<><C3A2> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ȿ<EFBFBD> Ŀ<><C4BF><EFBFBD><EFBFBD> ǥ<>õǵ<C3B5><C7B5><EFBFBD> <20>ý<EFBFBD><C3BD>ۿ<EFBFBD><DBBF><EFBFBD>
|
||||||
|
// <20><> <20>Լ<EFBFBD><D4BC><EFBFBD> ȣ<><C8A3><EFBFBD>մϴ<D5B4>.
|
||||||
|
HCURSOR CRaw2Bmp_MFCDlg::OnQueryDragIcon()
|
||||||
|
{
|
||||||
|
return static_cast<HCURSOR>(m_hIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CRaw2Bmp_MFCDlg::OnBnClickedOk()
|
||||||
|
{
|
||||||
|
// TODO: <20><><EFBFBD> <20><>Ʈ<EFBFBD><C6AE> <20>˸<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>ڵ带 <20>߰<EFBFBD><DFB0>մϴ<D5B4>.
|
||||||
|
|
||||||
|
//CString raw = _T("./Sample.RAW");
|
||||||
|
//CString dst = _T("./Sample.png");
|
||||||
|
|
||||||
|
CString raw = _T("./1.raw");
|
||||||
|
CString dst = _T("./1.png");
|
||||||
|
|
||||||
|
//IU.MakeImage(raw, dst, 2520, 3032); default 14 bit
|
||||||
|
//IU.MakeImage(raw, dst, 3072, 3072, 16);
|
||||||
|
//IU.MakeImage(raw, dst, 2520, 3032, 16);
|
||||||
|
//IU.MakeImage(raw, dst, 3052, 3052, 16);
|
||||||
|
|
||||||
|
//IU.ResizeImage (dst, 480, 480);
|
||||||
|
|
||||||
|
FTP_INFO *FI = new FTP_INFO;
|
||||||
|
FI->ConnectAddress = _T("192.168.51.5");
|
||||||
|
FI->ConnectPort = 21;
|
||||||
|
FI->Id = _T("chodadoo");
|
||||||
|
FI->Pw = _T("");
|
||||||
|
FI->DirPath = _T("");
|
||||||
|
FI->UploadFile = dst;
|
||||||
|
|
||||||
|
IU.FileUpload ( FI );
|
||||||
|
|
||||||
|
//CDialogEx::OnOK();
|
||||||
|
}
|
||||||
36
Raw2Bmp_MFC/Raw2Bmp_MFCDlg.h
Normal file
36
Raw2Bmp_MFC/Raw2Bmp_MFCDlg.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
// Raw2Bmp_MFCDlg.h : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ImageUtility.h"
|
||||||
|
|
||||||
|
// CRaw2Bmp_MFCDlg <20><>ȭ <20><><EFBFBD><EFBFBD>
|
||||||
|
class CRaw2Bmp_MFCDlg : public CDialogEx
|
||||||
|
{
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
public:
|
||||||
|
CRaw2Bmp_MFCDlg(CWnd* pParent = NULL); // ǥ<><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
// <20><>ȭ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
enum { IDD = IDD_RAW2BMP_MFC_DIALOG };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
protected:
|
||||||
|
HICON m_hIcon;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DEBD><EFBFBD> <20><> <20>Լ<EFBFBD>
|
||||||
|
virtual BOOL OnInitDialog();
|
||||||
|
afx_msg void OnPaint();
|
||||||
|
afx_msg HCURSOR OnQueryDragIcon();
|
||||||
|
DECLARE_MESSAGE_MAP()
|
||||||
|
public:
|
||||||
|
afx_msg void OnBnClickedOk();
|
||||||
|
|
||||||
|
CImageUtility IU;
|
||||||
|
};
|
||||||
103
Raw2Bmp_MFC/ReadMe.txt
Normal file
103
Raw2Bmp_MFC/ReadMe.txt
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
================================================================================
|
||||||
|
MFC <20><><EFBFBD>̺귯<CCBA><EAB7AF> : Raw2Bmp_MFC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>翡<EFBFBD><E7BFA1> <20><> Raw2Bmp_MFC <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD>
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>. <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> MFC<46><43> <20>⺻ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>Ӹ<EFBFBD> <20>ƴ϶<C6B4> <20><><EFBFBD><EFBFBD>
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD>α<EFBFBD><EFBFBD>ۼ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>⺻ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD> <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> Raw2Bmp_MFC <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><> <20><><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ԵǾ<D4B5> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
Raw2Bmp_MFC.vcxproj
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>縦 <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VC++ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Visual C++ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>縦 <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
<20>÷<EFBFBD><C3B7><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD>ɿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
Raw2Bmp_MFC.vcxproj.filters
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>縦 <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VC++ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
<20><> <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>. <20>̷<EFBFBD><CCB7><EFBFBD>
|
||||||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ư<><C6AF> <20><><EFBFBD>忡<EFBFBD><E5BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD>ȭ<EFBFBD><C8AD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ǥ<><C7A5><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
IDE<44><45><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>˴ϴ<CBB4>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ".cpp" <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "<22>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD>" <20><><EFBFBD>Ϳ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD>
|
||||||
|
<20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
|
||||||
|
Raw2Bmp_MFC.h
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20>⺻ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>. <20><><EFBFBD><EFBFBD><E2BFA1> <20>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
|
||||||
|
<20><><EFBFBD><EFBFBD>(Resource.h <20><><EFBFBD><EFBFBD>)<29><> <20><><EFBFBD><EFBFBD> <20>ְ<EFBFBD> CRaw2Bmp_MFCApp <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1>
|
||||||
|
Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
Raw2Bmp_MFC.cpp
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> Ŭ<><C5AC><EFBFBD><EFBFBD> CRaw2Bmp_MFCApp<70><70>(<28><>) <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>⺻ <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1>
|
||||||
|
<20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
Raw2Bmp_MFC.rc
|
||||||
|
<20><><EFBFBD>α<CEB1><D7B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> Microsoft Windows <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
<20><><EFBFBD><EFBFBD><E2BFA1> RES <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><CDB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>Ʈ<EFBFBD><C6AE> <20><> Ŀ<><C4BF><EFBFBD><EFBFBD>
|
||||||
|
<20><><EFBFBD>Ե˴ϴ<CBB4>. <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Microsoft Visual C++<2B><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> 1042<34><32> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
res\Raw2Bmp_MFC.ico
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>. <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
<20><> <20><><EFBFBD>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Raw2Bmp_MFC.rc<72><63> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ե˴ϴ<CBB4>.
|
||||||
|
|
||||||
|
res\Raw2Bmp_MFC.rc2
|
||||||
|
<20><> <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> Microsoft Visual C++ <20>̿<EFBFBD><CCBF><EFBFBD> <20>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD>
|
||||||
|
<20><><EFBFBD><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>. <20><><EFBFBD>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD>
|
||||||
|
<20><> <20><><EFBFBD>Ͽ<EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD> <20>մϴ<D5B4>.
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>翡<EFBFBD><E7BFA1> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20><>ȭ <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
Raw2Bmp_MFCDlg.h, Raw2Bmp_MFCDlg.cpp - <20><>ȭ <20><><EFBFBD><EFBFBD>
|
||||||
|
<20><> <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> CRaw2Bmp_MFCDlg Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>. <20><> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><> <20><>ȭ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>. <20><>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ø<EFBFBD><C3B8><EFBFBD>
|
||||||
|
Microsoft Visual C++<2B><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD> Raw2Bmp_MFC.rc<72><63> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD>Ÿ <20><><EFBFBD><EFBFBD>:
|
||||||
|
|
||||||
|
ActiveX <20><>Ʈ<EFBFBD><C6AE>
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD><EFBFBD><EFBFBD> ActiveX <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֵ<EFBFBD><D6B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
Windows <20><><EFBFBD><EFBFBD>
|
||||||
|
<20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD><EFBFBD><EFBFBD> TCP/IP <20><>Ʈ<EFBFBD><C6AE>ũ<EFBFBD><C5A9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD>Ÿ ǥ<><C7A5> <20><><EFBFBD><EFBFBD>:
|
||||||
|
|
||||||
|
StdAfx.h, StdAfx.cpp
|
||||||
|
<20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(PCH)<29><> Raw2Bmp_MFC.pch<63><68>
|
||||||
|
<20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> StdAfx.obj<62><6A> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>˴ϴ<CBB4>.
|
||||||
|
|
||||||
|
Resource.h
|
||||||
|
<20><> <20><><EFBFBD>ҽ<EFBFBD> ID<49><44> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> ǥ<><C7A5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
Microsoft Visual C++<2B><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>а<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
Raw2Bmp_MFC.manifest
|
||||||
|
<09><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20>Ŵ<EFBFBD><C5B4>佺Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Windows XP<58><50><EFBFBD><EFBFBD> Ư<><C6AF> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Side-by-Side
|
||||||
|
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>˴ϴ<CBB4>. <20>δ<EFBFBD><CEB4><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
<09><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<>ÿ<EFBFBD><C3BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ϰų<CFB0> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>մϴ<D5B4>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20>Ŵ<EFBFBD><C5B4>佺Ʈ<E4BDBA><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>ܺ<EFBFBD> .manifest <20><><EFBFBD>Ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Եǰų<C7B0> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> <20><><EFBFBD>·<EFBFBD>
|
||||||
|
<09><><EFBFBD><EFBFBD> <20><><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD>Ե<EFBFBD> <20><> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD>Ÿ <20><><EFBFBD><EFBFBD>:
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "TODO:"<22><> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20>߰<EFBFBD><DFB0>ϰų<CFB0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϴ<EFBFBD>
|
||||||
|
<EFBFBD>ҽ<EFBFBD> <20>ڵ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD>ϴ<EFBFBD>.
|
||||||
|
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD> DLL<4C><4C><EFBFBD><EFBFBD> MFC<46><43> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ش<EFBFBD> MFC DLL<4C><4C>
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>մϴ<D5B4>. <20><EFBFBD><D7B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20> ü<><C3BC><EFBFBD><EFBFBD> <20><>Ķ<EFBFBD><C4B6>
|
||||||
|
<EFBFBD>ٸ<EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD>ȭ<EFBFBD><C8AD> <20><><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD> MFC100XXX.DLL<4C><4C>
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>մϴ<D5B4>. <20><> <20>ΰ<EFBFBD><CEB0><EFBFBD> <20><EFBFBD><D7B8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڼ<EFBFBD><DABC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
MSDN <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Visual C++ <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><D7B8><EFBFBD>
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻʽÿ<EFBFBD>.
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
19
Raw2Bmp_MFC/Resource.h
Normal file
19
Raw2Bmp_MFC/Resource.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++<2B><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
// Raw2Bmp_MFC.rc<72><63><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>˴ϴ<CBB4>.
|
||||||
|
//
|
||||||
|
#define IDR_MAINFRAME 128
|
||||||
|
#define IDD_RAW2BMP_MFC_DIALOG 102
|
||||||
|
#define IDP_SOCKETS_INIT_FAILED 103
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>⺻<EFBFBD><E2BABB><EFBFBD>Դϴ<D4B4>.
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 129
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
BIN
Raw2Bmp_MFC/Sample.RAW
Normal file
BIN
Raw2Bmp_MFC/Sample.RAW
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/Sample.png
Normal file
BIN
Raw2Bmp_MFC/Sample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
BIN
Raw2Bmp_MFC/include/Jpeg.lib
Normal file
BIN
Raw2Bmp_MFC/include/Jpeg.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/Tiff.lib
Normal file
BIN
Raw2Bmp_MFC/include/Tiff.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/cximage.lib
Normal file
BIN
Raw2Bmp_MFC/include/cximage.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/cximaged.dll
Normal file
BIN
Raw2Bmp_MFC/include/cximaged.dll
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/jasper.lib
Normal file
BIN
Raw2Bmp_MFC/include/jasper.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/jbig.lib
Normal file
BIN
Raw2Bmp_MFC/include/jbig.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/libdcr.lib
Normal file
BIN
Raw2Bmp_MFC/include/libdcr.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/libpsd.lib
Normal file
BIN
Raw2Bmp_MFC/include/libpsd.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/mng.lib
Normal file
BIN
Raw2Bmp_MFC/include/mng.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/include/png.lib
Normal file
BIN
Raw2Bmp_MFC/include/png.lib
Normal file
Binary file not shown.
249
Raw2Bmp_MFC/include/stdint.h
Normal file
249
Raw2Bmp_MFC/include/stdint.h
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||||
|
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006-2008 Alexander Chemeris
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. The name of the author may be used to endorse or promote products
|
||||||
|
// derived from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _MSC_VER // [
|
||||||
|
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||||
|
#endif // _MSC_VER ]
|
||||||
|
|
||||||
|
#ifndef _MSC_STDINT_H_ // [
|
||||||
|
#define _MSC_STDINT_H_
|
||||||
|
|
||||||
|
#if _MSC_VER > 1000
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||||
|
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||||
|
// or compiler give many errors like this:
|
||||||
|
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||||
|
/*
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
# include <wchar.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||||
|
#ifndef _W64
|
||||||
|
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||||
|
# define _W64 __w64
|
||||||
|
# else
|
||||||
|
# define _W64
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.1 Integer types
|
||||||
|
|
||||||
|
// 7.18.1.1 Exact-width integer types
|
||||||
|
|
||||||
|
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||||
|
// realize that, e.g. char has the same size as __int8
|
||||||
|
// so we give up on __intX for them.
|
||||||
|
#if (_MSC_VER < 1300)
|
||||||
|
typedef signed char int8_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
typedef signed int int32_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
#else
|
||||||
|
typedef signed __int8 int8_t;
|
||||||
|
typedef signed __int16 int16_t;
|
||||||
|
typedef signed __int32 int32_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
#endif
|
||||||
|
typedef signed __int64 int64_t;
|
||||||
|
typedef unsigned __int64 uint64_t;
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.1.2 Minimum-width integer types
|
||||||
|
typedef int8_t int_least8_t;
|
||||||
|
typedef int16_t int_least16_t;
|
||||||
|
typedef int32_t int_least32_t;
|
||||||
|
typedef int64_t int_least64_t;
|
||||||
|
typedef uint8_t uint_least8_t;
|
||||||
|
typedef uint16_t uint_least16_t;
|
||||||
|
typedef uint32_t uint_least32_t;
|
||||||
|
typedef uint64_t uint_least64_t;
|
||||||
|
|
||||||
|
// 7.18.1.3 Fastest minimum-width integer types
|
||||||
|
typedef int8_t int_fast8_t;
|
||||||
|
typedef int16_t int_fast16_t;
|
||||||
|
typedef int32_t int_fast32_t;
|
||||||
|
typedef int64_t int_fast64_t;
|
||||||
|
typedef uint8_t uint_fast8_t;
|
||||||
|
typedef uint16_t uint_fast16_t;
|
||||||
|
typedef uint32_t uint_fast32_t;
|
||||||
|
typedef uint64_t uint_fast64_t;
|
||||||
|
|
||||||
|
// 7.18.1.4 Integer types capable of holding object pointers
|
||||||
|
#ifdef _WIN64 // [
|
||||||
|
typedef signed __int64 intptr_t;
|
||||||
|
typedef unsigned __int64 uintptr_t;
|
||||||
|
#else // _WIN64 ][
|
||||||
|
typedef _W64 signed int intptr_t;
|
||||||
|
typedef _W64 unsigned int uintptr_t;
|
||||||
|
#endif // _WIN64 ]
|
||||||
|
|
||||||
|
// 7.18.1.5 Greatest-width integer types
|
||||||
|
typedef int64_t intmax_t;
|
||||||
|
typedef uint64_t uintmax_t;
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.2 Limits of specified-width integer types
|
||||||
|
|
||||||
|
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||||
|
|
||||||
|
// 7.18.2.1 Limits of exact-width integer types
|
||||||
|
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||||
|
#define INT8_MAX _I8_MAX
|
||||||
|
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||||
|
#define INT16_MAX _I16_MAX
|
||||||
|
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||||
|
#define INT32_MAX _I32_MAX
|
||||||
|
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||||
|
#define INT64_MAX _I64_MAX
|
||||||
|
#define UINT8_MAX _UI8_MAX
|
||||||
|
#define UINT16_MAX _UI16_MAX
|
||||||
|
#define UINT32_MAX _UI32_MAX
|
||||||
|
#define UINT64_MAX _UI64_MAX
|
||||||
|
|
||||||
|
// 7.18.2.2 Limits of minimum-width integer types
|
||||||
|
#define INT_LEAST8_MIN INT8_MIN
|
||||||
|
#define INT_LEAST8_MAX INT8_MAX
|
||||||
|
#define INT_LEAST16_MIN INT16_MIN
|
||||||
|
#define INT_LEAST16_MAX INT16_MAX
|
||||||
|
#define INT_LEAST32_MIN INT32_MIN
|
||||||
|
#define INT_LEAST32_MAX INT32_MAX
|
||||||
|
#define INT_LEAST64_MIN INT64_MIN
|
||||||
|
#define INT_LEAST64_MAX INT64_MAX
|
||||||
|
#define UINT_LEAST8_MAX UINT8_MAX
|
||||||
|
#define UINT_LEAST16_MAX UINT16_MAX
|
||||||
|
#define UINT_LEAST32_MAX UINT32_MAX
|
||||||
|
#define UINT_LEAST64_MAX UINT64_MAX
|
||||||
|
|
||||||
|
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||||
|
#define INT_FAST8_MIN INT8_MIN
|
||||||
|
#define INT_FAST8_MAX INT8_MAX
|
||||||
|
#define INT_FAST16_MIN INT16_MIN
|
||||||
|
#define INT_FAST16_MAX INT16_MAX
|
||||||
|
#define INT_FAST32_MIN INT32_MIN
|
||||||
|
#define INT_FAST32_MAX INT32_MAX
|
||||||
|
#define INT_FAST64_MIN INT64_MIN
|
||||||
|
#define INT_FAST64_MAX INT64_MAX
|
||||||
|
#define UINT_FAST8_MAX UINT8_MAX
|
||||||
|
#define UINT_FAST16_MAX UINT16_MAX
|
||||||
|
#define UINT_FAST32_MAX UINT32_MAX
|
||||||
|
#define UINT_FAST64_MAX UINT64_MAX
|
||||||
|
|
||||||
|
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||||
|
#ifdef _WIN64 // [
|
||||||
|
# define INTPTR_MIN INT64_MIN
|
||||||
|
# define INTPTR_MAX INT64_MAX
|
||||||
|
# define UINTPTR_MAX UINT64_MAX
|
||||||
|
#else // _WIN64 ][
|
||||||
|
# define INTPTR_MIN INT32_MIN
|
||||||
|
# define INTPTR_MAX INT32_MAX
|
||||||
|
# define UINTPTR_MAX UINT32_MAX
|
||||||
|
#endif // _WIN64 ]
|
||||||
|
|
||||||
|
// 7.18.2.5 Limits of greatest-width integer types
|
||||||
|
#define INTMAX_MIN INT64_MIN
|
||||||
|
#define INTMAX_MAX INT64_MAX
|
||||||
|
#define UINTMAX_MAX UINT64_MAX
|
||||||
|
|
||||||
|
// 7.18.3 Limits of other integer types
|
||||||
|
|
||||||
|
#ifdef _WIN64 // [
|
||||||
|
# define PTRDIFF_MIN _I64_MIN
|
||||||
|
# define PTRDIFF_MAX _I64_MAX
|
||||||
|
#else // _WIN64 ][
|
||||||
|
# define PTRDIFF_MIN _I32_MIN
|
||||||
|
# define PTRDIFF_MAX _I32_MAX
|
||||||
|
#endif // _WIN64 ]
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_MIN INT_MIN
|
||||||
|
#define SIG_ATOMIC_MAX INT_MAX
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX // [
|
||||||
|
# ifdef _WIN64 // [
|
||||||
|
# define SIZE_MAX _UI64_MAX
|
||||||
|
# else // _WIN64 ][
|
||||||
|
# define SIZE_MAX _UI32_MAX
|
||||||
|
# endif // _WIN64 ]
|
||||||
|
#endif // SIZE_MAX ]
|
||||||
|
|
||||||
|
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||||
|
#ifndef WCHAR_MIN // [
|
||||||
|
# define WCHAR_MIN 0
|
||||||
|
#endif // WCHAR_MIN ]
|
||||||
|
#ifndef WCHAR_MAX // [
|
||||||
|
# define WCHAR_MAX _UI16_MAX
|
||||||
|
#endif // WCHAR_MAX ]
|
||||||
|
|
||||||
|
#define WINT_MIN 0
|
||||||
|
#define WINT_MAX _UI16_MAX
|
||||||
|
|
||||||
|
#endif // __STDC_LIMIT_MACROS ]
|
||||||
|
|
||||||
|
|
||||||
|
// 7.18.4 Limits of other integer types
|
||||||
|
|
||||||
|
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||||
|
|
||||||
|
// 7.18.4.1 Macros for minimum-width integer constants
|
||||||
|
|
||||||
|
#define INT8_C(val) val##i8
|
||||||
|
#define INT16_C(val) val##i16
|
||||||
|
#define INT32_C(val) val##i32
|
||||||
|
#define INT64_C(val) val##i64
|
||||||
|
|
||||||
|
#define UINT8_C(val) val##ui8
|
||||||
|
#define UINT16_C(val) val##ui16
|
||||||
|
#define UINT32_C(val) val##ui32
|
||||||
|
#define UINT64_C(val) val##ui64
|
||||||
|
|
||||||
|
// 7.18.4.2 Macros for greatest-width integer constants
|
||||||
|
#define INTMAX_C INT64_C
|
||||||
|
#define UINTMAX_C UINT64_C
|
||||||
|
|
||||||
|
#endif // __STDC_CONSTANT_MACROS ]
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _MSC_STDINT_H_ ]
|
||||||
221
Raw2Bmp_MFC/include/tif_xfile.cpp
Normal file
221
Raw2Bmp_MFC/include/tif_xfile.cpp
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
/*
|
||||||
|
* TIFF file IO, using CxFile.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
|
||||||
|
#include "../tiff/tiffiop.h"
|
||||||
|
#include "../tiff/tiffvers.h"
|
||||||
|
|
||||||
|
#include "xfile.h"
|
||||||
|
|
||||||
|
static tsize_t
|
||||||
|
_tiffReadProcEx(thandle_t fd, tdata_t buf, tsize_t size)
|
||||||
|
{
|
||||||
|
return (tsize_t)((CxFile*)fd)->Read(buf, 1, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static tsize_t
|
||||||
|
_tiffWriteProcEx(thandle_t fd, tdata_t buf, tsize_t size)
|
||||||
|
{
|
||||||
|
return (tsize_t)((CxFile*)fd)->Write(buf, 1, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static toff_t
|
||||||
|
_tiffSeekProcEx(thandle_t fd, toff_t off, int whence)
|
||||||
|
{
|
||||||
|
if ( off == 0xFFFFFFFF )
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
if (!((CxFile*)fd)->Seek(off, whence))
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
if (whence == SEEK_SET)
|
||||||
|
return off;
|
||||||
|
|
||||||
|
return (toff_t)((CxFile*)fd)->Tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return nonzero if error
|
||||||
|
static int
|
||||||
|
_tiffCloseProcEx(thandle_t /*fd*/)
|
||||||
|
{
|
||||||
|
// return !((CxFile*)fd)->Close(); // "//" needed for memory files <DP>
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
static toff_t
|
||||||
|
_tiffSizeProcEx(thandle_t fd)
|
||||||
|
{
|
||||||
|
return ((CxFile*)fd)->Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_tiffMapProcEx(thandle_t /*fd*/, tdata_t* /*pbase*/, toff_t* /*psize*/)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_tiffUnmapProcEx(thandle_t /*fd*/, tdata_t /*base*/, toff_t /*size*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open a TIFF file descriptor for read/writing.
|
||||||
|
/*
|
||||||
|
TIFF*
|
||||||
|
TIFFOpen(const char* name, const char* mode)
|
||||||
|
{
|
||||||
|
static const char module[] = "TIFFOpen";
|
||||||
|
FILE* stream = fopen(name, mode);
|
||||||
|
if (stream == NULL)
|
||||||
|
{
|
||||||
|
TIFFError(module, "%s: Cannot open", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (TIFFFdOpen((int)stream, name, mode));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
TIFF*
|
||||||
|
_TIFFFdOpen(void* fd, const char* name, const char* mode)
|
||||||
|
{
|
||||||
|
TIFF* tif;
|
||||||
|
|
||||||
|
tif = TIFFClientOpen(name, mode,
|
||||||
|
(thandle_t) fd,
|
||||||
|
_tiffReadProcEx, _tiffWriteProcEx, _tiffSeekProcEx, _tiffCloseProcEx,
|
||||||
|
_tiffSizeProcEx, _tiffMapProcEx, _tiffUnmapProcEx);
|
||||||
|
if (tif)
|
||||||
|
{
|
||||||
|
tif->tif_fd = (int)fd;
|
||||||
|
}
|
||||||
|
return (tif);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode)
|
||||||
|
{
|
||||||
|
return (_TIFFFdOpen(stream, "TIFF IMAGE", mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
extern char* malloc();
|
||||||
|
extern char* realloc();
|
||||||
|
#else
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tdata_t
|
||||||
|
_TIFFmalloc(tsize_t s)
|
||||||
|
{
|
||||||
|
return (malloc((size_t) s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_TIFFfree(tdata_t p)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
tdata_t
|
||||||
|
_TIFFrealloc(tdata_t p, tsize_t s)
|
||||||
|
{
|
||||||
|
return (realloc(p, (size_t) s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_TIFFmemset(tdata_t p, int v, tsize_t c)
|
||||||
|
{
|
||||||
|
memset(p, v, (size_t) c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
|
||||||
|
{
|
||||||
|
memcpy(d, s, (size_t) c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
|
||||||
|
{
|
||||||
|
return (memcmp(p1, p2, (size_t) c));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef UNICODE
|
||||||
|
#define DbgPrint wvsprintf
|
||||||
|
#define DbgPrint2 wsprintf
|
||||||
|
#define DbgMsgBox MessageBox
|
||||||
|
#else
|
||||||
|
#define DbgPrint wvsprintfA
|
||||||
|
#define DbgPrint2 wsprintfA
|
||||||
|
#define DbgMsgBox MessageBoxA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
Win32WarningHandler(const char* module, const char* fmt, va_list ap)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#if (!defined(_CONSOLE) && !defined(_WIN32_WCE) && defined(WIN32))
|
||||||
|
LPSTR szTitle;
|
||||||
|
LPSTR szTmp;
|
||||||
|
LPCSTR szTitleText = "%s Warning";
|
||||||
|
LPCSTR szDefaultModule = "TIFFLIB";
|
||||||
|
szTmp = (module == NULL) ? (LPSTR)szDefaultModule : (LPSTR)module;
|
||||||
|
if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmp) +
|
||||||
|
strlen(szTitleText) + strlen(fmt) + 128))) == NULL)
|
||||||
|
return;
|
||||||
|
DbgPrint2(szTitle, szTitleText, szTmp);
|
||||||
|
szTmp = szTitle + (strlen(szTitle)+2);
|
||||||
|
DbgPrint(szTmp, fmt, ap);
|
||||||
|
DbgMsgBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
|
||||||
|
LocalFree(szTitle);
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (module != NULL)
|
||||||
|
fprintf(stderr, "%s: ", module);
|
||||||
|
fprintf(stderr, "Warning, ");
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
fprintf(stderr, ".\n");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
|
||||||
|
|
||||||
|
static void
|
||||||
|
Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#if (!defined(_CONSOLE) && !defined(_WIN32_WCE) && defined(WIN32))
|
||||||
|
LPSTR szTitle;
|
||||||
|
LPSTR szTmp;
|
||||||
|
LPCSTR szTitleText = "%s Error";
|
||||||
|
LPCSTR szDefaultModule = "TIFFLIB";
|
||||||
|
szTmp = (module == NULL) ? (LPSTR)szDefaultModule : (LPSTR)module;
|
||||||
|
if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmp) +
|
||||||
|
strlen(szTitleText) + strlen(fmt) + 128))) == NULL)
|
||||||
|
return;
|
||||||
|
DbgPrint2(szTitle, szTitleText, szTmp);
|
||||||
|
szTmp = szTitle + (strlen(szTitle)+2);
|
||||||
|
DbgPrint(szTmp, fmt, ap);
|
||||||
|
DbgMsgBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
|
||||||
|
LocalFree(szTitle);
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (module != NULL)
|
||||||
|
fprintf(stderr, "%s: ", module);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
fprintf(stderr, ".\n");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
79
Raw2Bmp_MFC/include/xfile.h
Normal file
79
Raw2Bmp_MFC/include/xfile.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* File: xfile.h
|
||||||
|
* Purpose: General Purpose File Class
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
|
||||||
|
|
||||||
|
CxFile (c) 11/May/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
CxFile version 2.00 23/Aug/2002
|
||||||
|
CxFile version 2.10 16/Dec/2007
|
||||||
|
|
||||||
|
Special thanks to Chris Shearer Cooper for new features, enhancements and bugfixes
|
||||||
|
|
||||||
|
Covered code is provided under this license on an "as is" basis, without warranty
|
||||||
|
of any kind, either expressed or implied, including, without limitation, warranties
|
||||||
|
that the covered code is free of defects, merchantable, fit for a particular purpose
|
||||||
|
or non-infringing. The entire risk as to the quality and performance of the covered
|
||||||
|
code is with you. Should any covered code prove defective in any respect, you (not
|
||||||
|
the initial developer or any other contributor) assume the cost of any necessary
|
||||||
|
servicing, repair or correction. This disclaimer of warranty constitutes an essential
|
||||||
|
part of this license. No use of any covered code is authorized hereunder except under
|
||||||
|
this disclaimer.
|
||||||
|
|
||||||
|
Permission is hereby granted to use, copy, modify, and distribute this
|
||||||
|
source code, or portions hereof, for any purpose, including commercial applications,
|
||||||
|
freely and without fee, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if !defined(__xfile_h)
|
||||||
|
#define __xfile_h
|
||||||
|
|
||||||
|
#if defined (WIN32) || defined (_WIN32_WCE)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "ximadef.h"
|
||||||
|
|
||||||
|
class DLL_EXP CxFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxFile(void) { };
|
||||||
|
virtual ~CxFile() { };
|
||||||
|
|
||||||
|
virtual bool Close() = 0;
|
||||||
|
virtual size_t Read(void *buffer, size_t size, size_t count) = 0;
|
||||||
|
virtual size_t Write(const void *buffer, size_t size, size_t count) = 0;
|
||||||
|
virtual bool Seek(int32_t offset, int32_t origin) = 0;
|
||||||
|
virtual int32_t Tell() = 0;
|
||||||
|
virtual int32_t Size() = 0;
|
||||||
|
virtual bool Flush() = 0;
|
||||||
|
virtual bool Eof() = 0;
|
||||||
|
virtual int32_t Error() = 0;
|
||||||
|
virtual bool PutC(uint8_t c)
|
||||||
|
{
|
||||||
|
// Default implementation
|
||||||
|
size_t nWrote = Write(&c, 1, 1);
|
||||||
|
return (bool)(nWrote == 1);
|
||||||
|
}
|
||||||
|
virtual int32_t GetC() = 0;
|
||||||
|
virtual char * GetS(char *string, int32_t n) = 0;
|
||||||
|
virtual int32_t Scanf(const char *format, void* output) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__xfile_h
|
||||||
448
Raw2Bmp_MFC/include/ximabmp.cpp
Normal file
448
Raw2Bmp_MFC/include/ximabmp.cpp
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
/*
|
||||||
|
* File: ximabmp.cpp
|
||||||
|
* Purpose: Platform Independent BMP Image Class Loader and Writer
|
||||||
|
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximabmp.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
|
||||||
|
#include "ximaiter.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageBMP::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
BITMAPFILEHEADER hdr;
|
||||||
|
|
||||||
|
hdr.bfType = 0x4d42; // 'BM' WINDOWS_BITMAP_SIGNATURE
|
||||||
|
hdr.bfSize = GetSize() + 14 /*sizeof(BITMAPFILEHEADER)*/;
|
||||||
|
hdr.bfReserved1 = hdr.bfReserved2 = 0;
|
||||||
|
hdr.bfOffBits = 14 /*sizeof(BITMAPFILEHEADER)*/ + head.biSize + GetPaletteSize();
|
||||||
|
|
||||||
|
hdr.bfType = m_ntohs(hdr.bfType);
|
||||||
|
hdr.bfSize = m_ntohl(hdr.bfSize);
|
||||||
|
hdr.bfOffBits = m_ntohl(hdr.bfOffBits);
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (GetNumColors()==0 && AlphaIsValid()){
|
||||||
|
|
||||||
|
BITMAPINFOHEADER infohdr;
|
||||||
|
memcpy(&infohdr,&head,sizeof(BITMAPINFOHEADER));
|
||||||
|
infohdr.biCompression = BI_RGB;
|
||||||
|
infohdr.biBitCount = 32;
|
||||||
|
uint32_t dwEffWidth = ((((infohdr.biBitCount * infohdr.biWidth) + 31) / 32) * 4);
|
||||||
|
infohdr.biSizeImage = dwEffWidth * infohdr.biHeight;
|
||||||
|
|
||||||
|
hdr.bfSize = infohdr.biSize + infohdr.biSizeImage + 14 /*sizeof(BITMAPFILEHEADER)*/;
|
||||||
|
|
||||||
|
hdr.bfSize = m_ntohl(hdr.bfSize);
|
||||||
|
bihtoh(&infohdr);
|
||||||
|
|
||||||
|
// Write the file header
|
||||||
|
hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
|
||||||
|
hFile->Write(&infohdr,sizeof(BITMAPINFOHEADER),1);
|
||||||
|
//and DIB+ALPHA interlaced
|
||||||
|
uint8_t *srcalpha = AlphaGetPointer();
|
||||||
|
for(int32_t y = 0; y < infohdr.biHeight; ++y){
|
||||||
|
uint8_t *srcdib = GetBits(y);
|
||||||
|
for(int32_t x = 0; x < infohdr.biWidth; ++x){
|
||||||
|
hFile->Write(srcdib,3,1);
|
||||||
|
hFile->Write(srcalpha,1,1);
|
||||||
|
srcdib += 3;
|
||||||
|
++srcalpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
{
|
||||||
|
// Write the file header
|
||||||
|
hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
|
||||||
|
//copy attributes
|
||||||
|
memcpy(pDib,&head,sizeof(BITMAPINFOHEADER));
|
||||||
|
bihtoh((BITMAPINFOHEADER*)pDib);
|
||||||
|
// Write the DIB header and the pixels
|
||||||
|
hFile->Write(pDib,GetSize(),1);
|
||||||
|
bihtoh((BITMAPINFOHEADER*)pDib);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageBMP::Decode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
BITMAPFILEHEADER bf;
|
||||||
|
uint32_t off = hFile->Tell(); //<CSC>
|
||||||
|
cx_try {
|
||||||
|
if (hFile->Read(&bf,min(14,sizeof(bf)),1)==0) cx_throw("Not a BMP");
|
||||||
|
|
||||||
|
bf.bfSize = m_ntohl(bf.bfSize);
|
||||||
|
bf.bfOffBits = m_ntohl(bf.bfOffBits);
|
||||||
|
|
||||||
|
if (m_ntohs(bf.bfType) != BFT_BITMAP) { //do we have a RC HEADER?
|
||||||
|
bf.bfOffBits = 0L;
|
||||||
|
hFile->Seek(off,SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
BITMAPINFOHEADER bmpHeader;
|
||||||
|
if (!DibReadBitmapInfo(hFile,&bmpHeader)) cx_throw("Error reading BMP info");
|
||||||
|
uint32_t dwCompression=bmpHeader.biCompression;
|
||||||
|
uint32_t dwBitCount=bmpHeader.biBitCount; //preserve for BI_BITFIELDS compression <Thomas Ernst>
|
||||||
|
bool bIsOldBmp = bmpHeader.biSize == sizeof(BITMAPCOREHEADER);
|
||||||
|
|
||||||
|
bool bTopDownDib = bmpHeader.biHeight<0; //<Flanders> check if it's a top-down bitmap
|
||||||
|
if (bTopDownDib) bmpHeader.biHeight=-bmpHeader.biHeight;
|
||||||
|
|
||||||
|
if (info.nEscape == -1) {
|
||||||
|
// Return output dimensions only
|
||||||
|
head.biWidth = bmpHeader.biWidth;
|
||||||
|
head.biHeight = bmpHeader.biHeight;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_BMP;
|
||||||
|
cx_throw("output dimensions returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Create(bmpHeader.biWidth,bmpHeader.biHeight,bmpHeader.biBitCount,CXIMAGE_FORMAT_BMP))
|
||||||
|
cx_throw("");
|
||||||
|
|
||||||
|
SetXDPI((int32_t) floor(bmpHeader.biXPelsPerMeter * 254.0 / 10000.0 + 0.5));
|
||||||
|
SetYDPI((int32_t) floor(bmpHeader.biYPelsPerMeter * 254.0 / 10000.0 + 0.5));
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
RGBQUAD *pRgb = GetPalette();
|
||||||
|
if (pRgb){
|
||||||
|
if (bIsOldBmp){
|
||||||
|
// convert a old color table (3 byte entries) to a new
|
||||||
|
// color table (4 byte entries)
|
||||||
|
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1);
|
||||||
|
for (int32_t i=DibNumColors(&head)-1; i>=0; i--){
|
||||||
|
pRgb[i].rgbRed = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
|
||||||
|
pRgb[i].rgbBlue = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
|
||||||
|
pRgb[i].rgbGreen = ((RGBTRIPLE *)pRgb)[i].rgbtGreen;
|
||||||
|
pRgb[i].rgbReserved = (uint8_t)0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
|
||||||
|
//force rgbReserved=0, to avoid problems with some WinXp bitmaps
|
||||||
|
for (uint32_t i=0; i<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
switch (dwBitCount) {
|
||||||
|
case 32 :
|
||||||
|
uint32_t bfmask[3];
|
||||||
|
if (dwCompression == BI_BITFIELDS)
|
||||||
|
{
|
||||||
|
hFile->Read(bfmask, 12, 1);
|
||||||
|
} else {
|
||||||
|
bfmask[0]=0x00FF0000;
|
||||||
|
bfmask[1]=0x0000FF00;
|
||||||
|
bfmask[2]=0x000000FF;
|
||||||
|
}
|
||||||
|
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
|
||||||
|
if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
|
||||||
|
int32_t imagesize=4*head.biHeight*head.biWidth;
|
||||||
|
uint8_t* buff32=(uint8_t*)malloc(imagesize);
|
||||||
|
if (buff32){
|
||||||
|
hFile->Read(buff32, imagesize,1); // read in the pixels
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (dwCompression == BI_RGB){
|
||||||
|
AlphaCreate();
|
||||||
|
if (AlphaIsValid()){
|
||||||
|
bool bAlphaOk = false;
|
||||||
|
uint8_t* p;
|
||||||
|
for (int32_t y=0; y<head.biHeight; y++){
|
||||||
|
p = buff32 + 3 + head.biWidth * 4 * y;
|
||||||
|
for (int32_t x=0; x<head.biWidth; x++){
|
||||||
|
if (*p) bAlphaOk = true;
|
||||||
|
AlphaSet(x,y,*p);
|
||||||
|
p+=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fix if alpha pixels are all zero
|
||||||
|
if (!bAlphaOk) AlphaInvert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
Bitfield2RGB(buff32,bfmask[0],bfmask[1],bfmask[2],32);
|
||||||
|
free(buff32);
|
||||||
|
} else cx_throw("can't allocate memory");
|
||||||
|
} else cx_throw("unknown compression");
|
||||||
|
break;
|
||||||
|
case 24 :
|
||||||
|
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
|
||||||
|
if (dwCompression == BI_RGB){
|
||||||
|
hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
|
||||||
|
} else cx_throw("unknown compression");
|
||||||
|
break;
|
||||||
|
case 16 :
|
||||||
|
{
|
||||||
|
uint32_t bfmask[3];
|
||||||
|
if (dwCompression == BI_BITFIELDS)
|
||||||
|
{
|
||||||
|
hFile->Read(bfmask, 12, 1);
|
||||||
|
} else {
|
||||||
|
bfmask[0]=0x7C00; bfmask[1]=0x3E0; bfmask[2]=0x1F; //RGB555
|
||||||
|
}
|
||||||
|
// bf.bfOffBits required after the bitfield mask <Cui Ying Jie>
|
||||||
|
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
|
||||||
|
// read in the pixels
|
||||||
|
hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1);
|
||||||
|
// transform into RGB
|
||||||
|
Bitfield2RGB(info.pImage,bfmask[0],bfmask[1],bfmask[2],16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8 :
|
||||||
|
case 4 :
|
||||||
|
case 1 :
|
||||||
|
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
|
||||||
|
switch (dwCompression) {
|
||||||
|
case BI_RGB :
|
||||||
|
hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
|
||||||
|
break;
|
||||||
|
case BI_RLE4 :
|
||||||
|
{
|
||||||
|
uint8_t status_byte = 0;
|
||||||
|
uint8_t second_byte = 0;
|
||||||
|
int32_t scanline = 0;
|
||||||
|
int32_t bits = 0;
|
||||||
|
BOOL low_nibble = FALSE;
|
||||||
|
CImageIterator iter(this);
|
||||||
|
|
||||||
|
for (BOOL bContinue = TRUE; bContinue && hFile->Read(&status_byte, sizeof(uint8_t), 1);) {
|
||||||
|
|
||||||
|
switch (status_byte) {
|
||||||
|
case RLE_COMMAND :
|
||||||
|
hFile->Read(&status_byte, sizeof(uint8_t), 1);
|
||||||
|
switch (status_byte) {
|
||||||
|
case RLE_ENDOFLINE :
|
||||||
|
bits = 0;
|
||||||
|
scanline++;
|
||||||
|
low_nibble = FALSE;
|
||||||
|
break;
|
||||||
|
case RLE_ENDOFBITMAP :
|
||||||
|
bContinue=FALSE;
|
||||||
|
break;
|
||||||
|
case RLE_DELTA :
|
||||||
|
{
|
||||||
|
// read the delta values
|
||||||
|
uint8_t delta_x;
|
||||||
|
uint8_t delta_y;
|
||||||
|
hFile->Read(&delta_x, sizeof(uint8_t), 1);
|
||||||
|
hFile->Read(&delta_y, sizeof(uint8_t), 1);
|
||||||
|
// apply them
|
||||||
|
bits += delta_x / 2;
|
||||||
|
scanline += delta_y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||||
|
uint8_t *sline = iter.GetRow(scanline);
|
||||||
|
for (int32_t i = 0; i < status_byte; i++) {
|
||||||
|
if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
|
||||||
|
if (low_nibble) {
|
||||||
|
if (i&1)
|
||||||
|
*(sline + bits) |= (second_byte & 0x0f);
|
||||||
|
else
|
||||||
|
*(sline + bits) |= (second_byte & 0xf0)>>4;
|
||||||
|
bits++;
|
||||||
|
} else {
|
||||||
|
if (i&1)
|
||||||
|
*(sline + bits) = (uint8_t)(second_byte & 0x0f)<<4;
|
||||||
|
else
|
||||||
|
*(sline + bits) = (uint8_t)(second_byte & 0xf0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i & 1) && (i != (status_byte - 1)))
|
||||||
|
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||||
|
|
||||||
|
low_nibble = !low_nibble;
|
||||||
|
}
|
||||||
|
if ((((status_byte+1) >> 1) & 1 ) == 1)
|
||||||
|
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
{
|
||||||
|
uint8_t *sline = iter.GetRow(scanline);
|
||||||
|
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||||
|
for (unsigned i = 0; i < status_byte; i++) {
|
||||||
|
if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
|
||||||
|
if (low_nibble) {
|
||||||
|
if (i&1)
|
||||||
|
*(sline + bits) |= (second_byte & 0x0f);
|
||||||
|
else
|
||||||
|
*(sline + bits) |= (second_byte & 0xf0)>>4;
|
||||||
|
bits++;
|
||||||
|
} else {
|
||||||
|
if (i&1)
|
||||||
|
*(sline + bits) = (uint8_t)(second_byte & 0x0f)<<4;
|
||||||
|
else
|
||||||
|
*(sline + bits) = (uint8_t)(second_byte & 0xf0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
low_nibble = !low_nibble;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BI_RLE8 :
|
||||||
|
{
|
||||||
|
uint8_t status_byte = 0;
|
||||||
|
uint8_t second_byte = 0;
|
||||||
|
int32_t scanline = 0;
|
||||||
|
int32_t bits = 0;
|
||||||
|
CImageIterator iter(this);
|
||||||
|
|
||||||
|
for (BOOL bContinue = TRUE; bContinue && hFile->Read(&status_byte, sizeof(uint8_t), 1);) {
|
||||||
|
switch (status_byte) {
|
||||||
|
case RLE_COMMAND :
|
||||||
|
hFile->Read(&status_byte, sizeof(uint8_t), 1);
|
||||||
|
switch (status_byte) {
|
||||||
|
case RLE_ENDOFLINE :
|
||||||
|
bits = 0;
|
||||||
|
scanline++;
|
||||||
|
break;
|
||||||
|
case RLE_ENDOFBITMAP :
|
||||||
|
bContinue=FALSE;
|
||||||
|
break;
|
||||||
|
case RLE_DELTA :
|
||||||
|
{
|
||||||
|
// read the delta values
|
||||||
|
uint8_t delta_x;
|
||||||
|
uint8_t delta_y;
|
||||||
|
hFile->Read(&delta_x, sizeof(uint8_t), 1);
|
||||||
|
hFile->Read(&delta_y, sizeof(uint8_t), 1);
|
||||||
|
// apply them
|
||||||
|
bits += delta_x;
|
||||||
|
scanline += delta_y;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1);
|
||||||
|
// align run length to even number of bytes
|
||||||
|
if ((status_byte & 1) == 1)
|
||||||
|
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||||
|
bits += status_byte;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
uint8_t *sline = iter.GetRow(scanline);
|
||||||
|
hFile->Read(&second_byte, sizeof(uint8_t), 1);
|
||||||
|
for (unsigned i = 0; i < status_byte; i++) {
|
||||||
|
if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
|
||||||
|
*(sline + bits) = second_byte;
|
||||||
|
bits++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
cx_throw("compression type not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bTopDownDib) Flip(); //<Flanders>
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_BMP) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* ReadDibBitmapInfo()
|
||||||
|
*
|
||||||
|
* Will read a file in DIB format and return a global HANDLE to its
|
||||||
|
* BITMAPINFO. This function will work with both "old" and "new"
|
||||||
|
* bitmap formats, but will always return a "new" BITMAPINFO.
|
||||||
|
*/
|
||||||
|
bool CxImageBMP::DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib)
|
||||||
|
{
|
||||||
|
if ((fh==NULL)||(pdib==NULL)) return false;
|
||||||
|
|
||||||
|
if (fh->Read(pdib,sizeof(BITMAPINFOHEADER),1)==0) return false;
|
||||||
|
|
||||||
|
bihtoh(pdib);
|
||||||
|
|
||||||
|
switch (pdib->biSize) // what type of bitmap info is this?
|
||||||
|
{
|
||||||
|
case sizeof(BITMAPINFOHEADER):
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 64: //sizeof(OS2_BMP_HEADER):
|
||||||
|
fh->Seek((int32_t)(64 - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 124: //sizeof(BITMAPV5HEADER):
|
||||||
|
fh->Seek((long)(124-sizeof(BITMAPINFOHEADER)), SEEK_CUR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sizeof(BITMAPCOREHEADER):
|
||||||
|
{
|
||||||
|
BITMAPCOREHEADER bc = *(BITMAPCOREHEADER*)pdib;
|
||||||
|
pdib->biSize = bc.bcSize;
|
||||||
|
pdib->biWidth = (uint32_t)bc.bcWidth;
|
||||||
|
pdib->biHeight = (uint32_t)bc.bcHeight;
|
||||||
|
pdib->biPlanes = bc.bcPlanes;
|
||||||
|
pdib->biBitCount = bc.bcBitCount;
|
||||||
|
pdib->biCompression = BI_RGB;
|
||||||
|
pdib->biSizeImage = 0;
|
||||||
|
pdib->biXPelsPerMeter = 0;
|
||||||
|
pdib->biYPelsPerMeter = 0;
|
||||||
|
pdib->biClrUsed = 0;
|
||||||
|
pdib->biClrImportant = 0;
|
||||||
|
|
||||||
|
fh->Seek((int32_t)(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER)), SEEK_CUR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//give a last chance
|
||||||
|
if (pdib->biSize>(sizeof(BITMAPINFOHEADER))&&
|
||||||
|
(pdib->biSizeImage>=(uint32_t)(pdib->biHeight*((((pdib->biBitCount*pdib->biWidth)+31)/32)*4)))&&
|
||||||
|
(pdib->biPlanes==1)&&(pdib->biClrUsed==0))
|
||||||
|
{
|
||||||
|
if (pdib->biCompression==BI_RGB)
|
||||||
|
fh->Seek((int32_t)(pdib->biSize - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FixBitmapInfo(pdib);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_BMP
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
79
Raw2Bmp_MFC/include/ximabmp.h
Normal file
79
Raw2Bmp_MFC/include/ximabmp.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* File: ximabmp.h
|
||||||
|
* Purpose: BMP Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageBMP (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
|
||||||
|
*
|
||||||
|
* original CImageBMP and CImageIterator implementation are:
|
||||||
|
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
|
||||||
|
*
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__ximaBMP_h)
|
||||||
|
#define __ximaBMP_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
const int32_t RLE_COMMAND = 0;
|
||||||
|
const int32_t RLE_ENDOFLINE = 0;
|
||||||
|
const int32_t RLE_ENDOFBITMAP = 1;
|
||||||
|
const int32_t RLE_DELTA = 2;
|
||||||
|
|
||||||
|
#if !defined(BI_RLE8)
|
||||||
|
#define BI_RLE8 1L
|
||||||
|
#endif
|
||||||
|
#if !defined(BI_RLE4)
|
||||||
|
#define BI_RLE4 2L
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
|
||||||
|
class CxImageBMP: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImageBMP(): CxImage(CXIMAGE_FORMAT_BMP) {};
|
||||||
|
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BFT_ICON 0x4349 /* 'IC' */
|
||||||
|
#define BFT_BITMAP 0x4d42 /* 'BM' */
|
||||||
|
#define BFT_CURSOR 0x5450 /* 'PT' */
|
||||||
|
|
||||||
|
#ifndef WIDTHBYTES
|
||||||
|
#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DibWidthBytesN(lpbi, n) (uint32_t)WIDTHBYTES((uint32_t)(lpbi)->biWidth * (uint32_t)(n))
|
||||||
|
#define DibWidthBytes(lpbi) DibWidthBytesN(lpbi, (lpbi)->biBitCount)
|
||||||
|
|
||||||
|
#define DibSizeImage(lpbi) ((lpbi)->biSizeImage == 0 \
|
||||||
|
? ((uint32_t)(uint32_t)DibWidthBytes(lpbi) * (uint32_t)(uint32_t)(lpbi)->biHeight) \
|
||||||
|
: (lpbi)->biSizeImage)
|
||||||
|
|
||||||
|
#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
|
||||||
|
? (int32_t)(1 << (int32_t)(lpbi)->biBitCount) \
|
||||||
|
: (int32_t)(lpbi)->biClrUsed)
|
||||||
|
|
||||||
|
#define FixBitmapInfo(lpbi) if ((lpbi)->biSizeImage == 0) \
|
||||||
|
(lpbi)->biSizeImage = DibSizeImage(lpbi); \
|
||||||
|
if ((lpbi)->biClrUsed == 0) \
|
||||||
|
(lpbi)->biClrUsed = DibNumColors(lpbi); \
|
||||||
|
|
||||||
|
#endif
|
||||||
59
Raw2Bmp_MFC/include/ximacfg.h
Normal file
59
Raw2Bmp_MFC/include/ximacfg.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#if !defined(__ximaCFG_h)
|
||||||
|
#define __ximaCFG_h
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CxImage supported features
|
||||||
|
#define CXIMAGE_SUPPORT_ALPHA 1
|
||||||
|
#define CXIMAGE_SUPPORT_SELECTION 1
|
||||||
|
#define CXIMAGE_SUPPORT_TRANSFORMATION 1
|
||||||
|
#define CXIMAGE_SUPPORT_DSP 1
|
||||||
|
#define CXIMAGE_SUPPORT_LAYERS 1
|
||||||
|
#define CXIMAGE_SUPPORT_INTERPOLATION 1
|
||||||
|
|
||||||
|
#define CXIMAGE_SUPPORT_DECODE 1
|
||||||
|
#define CXIMAGE_SUPPORT_ENCODE 1 //<vho><T.Peck>
|
||||||
|
#define CXIMAGE_SUPPORT_WINDOWS 1
|
||||||
|
#define CXIMAGE_SUPPORT_EXIF 1
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CxImage supported formats
|
||||||
|
#define CXIMAGE_SUPPORT_BMP 1
|
||||||
|
#define CXIMAGE_SUPPORT_GIF 1
|
||||||
|
#define CXIMAGE_SUPPORT_JPG 1
|
||||||
|
#define CXIMAGE_SUPPORT_PNG 1
|
||||||
|
#define CXIMAGE_SUPPORT_ICO 1
|
||||||
|
#define CXIMAGE_SUPPORT_TIF 1
|
||||||
|
#define CXIMAGE_SUPPORT_TGA 1
|
||||||
|
#define CXIMAGE_SUPPORT_PCX 1
|
||||||
|
#define CXIMAGE_SUPPORT_WBMP 1
|
||||||
|
#define CXIMAGE_SUPPORT_WMF 1
|
||||||
|
|
||||||
|
#define CXIMAGE_SUPPORT_JP2 1
|
||||||
|
#define CXIMAGE_SUPPORT_JPC 1
|
||||||
|
#define CXIMAGE_SUPPORT_PGX 1
|
||||||
|
#define CXIMAGE_SUPPORT_PNM 1
|
||||||
|
#define CXIMAGE_SUPPORT_RAS 1
|
||||||
|
|
||||||
|
#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm
|
||||||
|
|
||||||
|
#define CXIMAGE_SUPPORT_MNG 1
|
||||||
|
#define CXIMAGE_SUPPORT_SKA 1
|
||||||
|
#define CXIMAGE_SUPPORT_RAW 1
|
||||||
|
#define CXIMAGE_SUPPORT_PSD 1
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define CXIMAGE_MAX_MEMORY 268435456
|
||||||
|
|
||||||
|
#define CXIMAGE_DEFAULT_DPI 96
|
||||||
|
|
||||||
|
#define CXIMAGE_ERR_NOFILE "null file handler"
|
||||||
|
#define CXIMAGE_ERR_NOIMAGE "null image!!!"
|
||||||
|
|
||||||
|
#define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 1
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//color to grey mapping <H. Muelner> <jurgene>
|
||||||
|
//#define RGB2GRAY(r,g,b) (((b)*114 + (g)*587 + (r)*299)/1000)
|
||||||
|
#define RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10)
|
||||||
|
|
||||||
|
#endif
|
||||||
210
Raw2Bmp_MFC/include/ximadef.h
Normal file
210
Raw2Bmp_MFC/include/ximadef.h
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
#if !defined(__ximadefs_h)
|
||||||
|
#define __ximadefs_h
|
||||||
|
|
||||||
|
#include "ximacfg.h"
|
||||||
|
|
||||||
|
#if /*defined(_AFXDLL)||*/defined(_USRDLL)
|
||||||
|
#define DLL_EXP __declspec(dllexport)
|
||||||
|
#elif defined(_MSC_VER)&&(_MSC_VER<1200)
|
||||||
|
#define DLL_EXP __declspec(dllimport)
|
||||||
|
#else
|
||||||
|
#define DLL_EXP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
#define cx_try try
|
||||||
|
#define cx_throw(message) throw(message)
|
||||||
|
#define cx_catch catch (const char *message)
|
||||||
|
#else
|
||||||
|
#define cx_try bool cx_error=false;
|
||||||
|
#define cx_throw(message) {cx_error=true; if(strcmp(message,"")) strncpy(info.szLastError,message,255); goto cx_error_catch;}
|
||||||
|
#define cx_catch cx_error_catch: char message[]=""; if(cx_error)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JP2 || CXIMAGE_SUPPORT_JPC || CXIMAGE_SUPPORT_PGX || CXIMAGE_SUPPORT_PNM || CXIMAGE_SUPPORT_RAS
|
||||||
|
#define CXIMAGE_SUPPORT_JASPER 1
|
||||||
|
#else
|
||||||
|
#define CXIMAGE_SUPPORT_JASPER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_DSP
|
||||||
|
#undef CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
#define CXIMAGE_SUPPORT_TRANSFORMATION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TRANSFORMATION || CXIMAGE_SUPPORT_TIF || CXIMAGE_SUPPORT_TGA || CXIMAGE_SUPPORT_BMP || CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
#define CXIMAGE_SUPPORT_BASICTRANSFORMATIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_DSP || CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
#undef CXIMAGE_SUPPORT_INTERPOLATION
|
||||||
|
#define CXIMAGE_SUPPORT_INTERPOLATION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CXIMAGE_SUPPORT_DECODE == 0)
|
||||||
|
#undef CXIMAGE_SUPPORT_EXIF
|
||||||
|
#define CXIMAGE_SUPPORT_EXIF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (_WIN32_WCE)
|
||||||
|
#undef CXIMAGE_SUPPORT_WMF
|
||||||
|
#define CXIMAGE_SUPPORT_WMF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WIN32) && !defined(_WIN32_WCE)
|
||||||
|
#undef CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
#define CXIMAGE_SUPPORT_WINDOWS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PI
|
||||||
|
#define PI 3.141592653589793f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
|
||||||
|
#ifndef _COMPLEX_DEFINED
|
||||||
|
|
||||||
|
typedef struct tagcomplex {
|
||||||
|
double x,y;
|
||||||
|
} _complex;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _cabs(c) sqrt(c.x*c.x+c.y*c.y)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||||
|
#include "stdint.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WIN32) && !defined(_WIN32_WCE)
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
typedef uint32_t COLORREF;
|
||||||
|
typedef void* HANDLE;
|
||||||
|
typedef void* HRGN;
|
||||||
|
|
||||||
|
#ifndef BOOL
|
||||||
|
#define BOOL bool
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE true
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TCHAR
|
||||||
|
#define TCHAR char
|
||||||
|
#define _T
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct tagRECT
|
||||||
|
{
|
||||||
|
int32_t left;
|
||||||
|
int32_t top;
|
||||||
|
int32_t right;
|
||||||
|
int32_t bottom;
|
||||||
|
} RECT;
|
||||||
|
|
||||||
|
typedef struct tagPOINT
|
||||||
|
{
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
} POINT;
|
||||||
|
|
||||||
|
typedef struct tagRGBQUAD {
|
||||||
|
uint8_t rgbBlue;
|
||||||
|
uint8_t rgbGreen;
|
||||||
|
uint8_t rgbRed;
|
||||||
|
uint8_t rgbReserved;
|
||||||
|
} RGBQUAD;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct tagBITMAPINFOHEADER{
|
||||||
|
uint32_t biSize;
|
||||||
|
int32_t biWidth;
|
||||||
|
int32_t biHeight;
|
||||||
|
uint16_t biPlanes;
|
||||||
|
uint16_t biBitCount;
|
||||||
|
uint32_t biCompression;
|
||||||
|
uint32_t biSizeImage;
|
||||||
|
int32_t biXPelsPerMeter;
|
||||||
|
int32_t biYPelsPerMeter;
|
||||||
|
uint32_t biClrUsed;
|
||||||
|
uint32_t biClrImportant;
|
||||||
|
} BITMAPINFOHEADER;
|
||||||
|
|
||||||
|
typedef struct tagBITMAPFILEHEADER {
|
||||||
|
uint16_t bfType;
|
||||||
|
uint32_t bfSize;
|
||||||
|
uint16_t bfReserved1;
|
||||||
|
uint16_t bfReserved2;
|
||||||
|
uint32_t bfOffBits;
|
||||||
|
} BITMAPFILEHEADER;
|
||||||
|
|
||||||
|
typedef struct tagBITMAPCOREHEADER {
|
||||||
|
uint32_t bcSize;
|
||||||
|
uint16_t bcWidth;
|
||||||
|
uint16_t bcHeight;
|
||||||
|
uint16_t bcPlanes;
|
||||||
|
uint16_t bcBitCount;
|
||||||
|
} BITMAPCOREHEADER;
|
||||||
|
|
||||||
|
typedef struct tagRGBTRIPLE {
|
||||||
|
uint8_t rgbtBlue;
|
||||||
|
uint8_t rgbtGreen;
|
||||||
|
uint8_t rgbtRed;
|
||||||
|
} RGBTRIPLE;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#define BI_RGB 0L
|
||||||
|
#define BI_RLE8 1L
|
||||||
|
#define BI_RLE4 2L
|
||||||
|
#define BI_BITFIELDS 3L
|
||||||
|
|
||||||
|
#define GetRValue(rgb) ((uint8_t)(rgb))
|
||||||
|
#define GetGValue(rgb) ((uint8_t)(((uint16_t)(rgb)) >> 8))
|
||||||
|
#define GetBValue(rgb) ((uint8_t)((rgb)>>16))
|
||||||
|
#define RGB(r,g,b) ((COLORREF)(((uint8_t)(r)|((uint16_t)((uint8_t)(g))<<8))|(((uint32_t)(uint8_t)(b))<<16)))
|
||||||
|
|
||||||
|
#ifndef _COMPLEX_DEFINED
|
||||||
|
|
||||||
|
typedef struct tagcomplex {
|
||||||
|
double x,y;
|
||||||
|
} _complex;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _cabs(c) sqrt(c.x*c.x+c.y*c.y)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //__ximadefs
|
||||||
3767
Raw2Bmp_MFC/include/ximadsp.cpp
Normal file
3767
Raw2Bmp_MFC/include/ximadsp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1159
Raw2Bmp_MFC/include/ximaenc.cpp
Normal file
1159
Raw2Bmp_MFC/include/ximaenc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
877
Raw2Bmp_MFC/include/ximaexif.cpp
Normal file
877
Raw2Bmp_MFC/include/ximaexif.cpp
Normal file
@@ -0,0 +1,877 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaexif.cpp
|
||||||
|
* Purpose: EXIF reader
|
||||||
|
* 18/Aug/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
* based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximajpg.h"
|
||||||
|
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageJPG::CxExifInfo::CxExifInfo(EXIFINFO* info)
|
||||||
|
{
|
||||||
|
if (info) {
|
||||||
|
m_exifinfo = info;
|
||||||
|
freeinfo = false;
|
||||||
|
} else {
|
||||||
|
m_exifinfo = new EXIFINFO;
|
||||||
|
memset(m_exifinfo,0,sizeof(EXIFINFO));
|
||||||
|
freeinfo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_szLastError[0]='\0';
|
||||||
|
ExifImageWidth = MotorolaOrder = 0;
|
||||||
|
SectionsRead=0;
|
||||||
|
memset(&Sections, 0, MAX_SECTIONS * sizeof(Section_t));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageJPG::CxExifInfo::~CxExifInfo()
|
||||||
|
{
|
||||||
|
for(int32_t i=0;i<MAX_SECTIONS;i++) if(Sections[i].Data) free(Sections[i].Data);
|
||||||
|
if (freeinfo) delete m_exifinfo;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int32_t nReadMode)
|
||||||
|
{
|
||||||
|
int32_t a;
|
||||||
|
int32_t HaveCom = FALSE;
|
||||||
|
|
||||||
|
a = hFile->GetC();
|
||||||
|
|
||||||
|
if (a != 0xff || hFile->GetC() != M_SOI){
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;){
|
||||||
|
int32_t itemlen;
|
||||||
|
int32_t marker = 0;
|
||||||
|
int32_t ll,lh, got;
|
||||||
|
uint8_t * Data;
|
||||||
|
|
||||||
|
if (SectionsRead >= MAX_SECTIONS){
|
||||||
|
strcpy(m_szLastError,"Too many sections in jpg file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (a=0;a<7;a++){
|
||||||
|
marker = hFile->GetC();
|
||||||
|
if (marker != 0xff) break;
|
||||||
|
|
||||||
|
if (a >= 6){
|
||||||
|
printf("too many padding bytes\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (marker == 0xff){
|
||||||
|
// 0xff is legal padding, but if we get that many, something's wrong.
|
||||||
|
strcpy(m_szLastError,"too many padding bytes!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sections[SectionsRead].Type = marker;
|
||||||
|
|
||||||
|
// Read the length of the section.
|
||||||
|
lh = hFile->GetC();
|
||||||
|
ll = hFile->GetC();
|
||||||
|
|
||||||
|
itemlen = (lh << 8) | ll;
|
||||||
|
|
||||||
|
if (itemlen < 2){
|
||||||
|
strcpy(m_szLastError,"invalid marker");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sections[SectionsRead].Size = itemlen;
|
||||||
|
|
||||||
|
Data = (uint8_t *)malloc(itemlen);
|
||||||
|
if (Data == NULL){
|
||||||
|
strcpy(m_szLastError,"Could not allocate memory");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Sections[SectionsRead].Data = Data;
|
||||||
|
|
||||||
|
// Store first two pre-read bytes.
|
||||||
|
Data[0] = (uint8_t)lh;
|
||||||
|
Data[1] = (uint8_t)ll;
|
||||||
|
|
||||||
|
got = hFile->Read(Data+2, 1, itemlen-2); // Read the whole section.
|
||||||
|
if (got != itemlen-2){
|
||||||
|
strcpy(m_szLastError,"Premature end of file?");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SectionsRead += 1;
|
||||||
|
|
||||||
|
switch(marker){
|
||||||
|
|
||||||
|
case M_SOS: // stop before hitting compressed data
|
||||||
|
// If reading entire image is requested, read the rest of the data.
|
||||||
|
if (nReadMode & EXIF_READ_IMAGE){
|
||||||
|
int32_t cp, ep, size;
|
||||||
|
// Determine how much file is left.
|
||||||
|
cp = hFile->Tell();
|
||||||
|
hFile->Seek(0, SEEK_END);
|
||||||
|
ep = hFile->Tell();
|
||||||
|
hFile->Seek(cp, SEEK_SET);
|
||||||
|
|
||||||
|
size = ep-cp;
|
||||||
|
Data = (uint8_t *)malloc(size);
|
||||||
|
if (Data == NULL){
|
||||||
|
strcpy(m_szLastError,"could not allocate data for entire image");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
got = hFile->Read(Data, 1, size);
|
||||||
|
if (got != size){
|
||||||
|
strcpy(m_szLastError,"could not read the rest of the image");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sections[SectionsRead].Data = Data;
|
||||||
|
Sections[SectionsRead].Size = size;
|
||||||
|
Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
|
||||||
|
SectionsRead ++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case M_EOI: // in case it's a tables-only JPEG stream
|
||||||
|
printf("No image in jpeg!\n");
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
case M_COM: // Comment section
|
||||||
|
if (HaveCom || ((nReadMode & EXIF_READ_EXIF) == 0)){
|
||||||
|
// Discard this section.
|
||||||
|
free(Sections[--SectionsRead].Data);
|
||||||
|
Sections[SectionsRead].Data=0;
|
||||||
|
}else{
|
||||||
|
process_COM(Data, itemlen);
|
||||||
|
HaveCom = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_JFIF:
|
||||||
|
// Regular jpegs always have this tag, exif images have the exif
|
||||||
|
// marker instead, althogh ACDsee will write images with both markers.
|
||||||
|
// this program will re-create this marker on absence of exif marker.
|
||||||
|
// hence no need to keep the copy from the file.
|
||||||
|
free(Sections[--SectionsRead].Data);
|
||||||
|
Sections[SectionsRead].Data=0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_EXIF:
|
||||||
|
// Seen files from some 'U-lead' software with Vivitar scanner
|
||||||
|
// that uses marker 31 for non exif stuff. Thus make sure
|
||||||
|
// it says 'Exif' in the section before treating it as exif.
|
||||||
|
if ((nReadMode & EXIF_READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){
|
||||||
|
m_exifinfo->IsExif = process_EXIF((uint8_t *)Data+2, itemlen);
|
||||||
|
}else{
|
||||||
|
// Discard this section.
|
||||||
|
free(Sections[--SectionsRead].Data);
|
||||||
|
Sections[SectionsRead].Data=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_SOF0:
|
||||||
|
case M_SOF1:
|
||||||
|
case M_SOF2:
|
||||||
|
case M_SOF3:
|
||||||
|
case M_SOF5:
|
||||||
|
case M_SOF6:
|
||||||
|
case M_SOF7:
|
||||||
|
case M_SOF9:
|
||||||
|
case M_SOF10:
|
||||||
|
case M_SOF11:
|
||||||
|
case M_SOF13:
|
||||||
|
case M_SOF14:
|
||||||
|
case M_SOF15:
|
||||||
|
process_SOFn(Data, marker);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Skip any other sections.
|
||||||
|
//if (ShowTags) printf("Jpeg section marker 0x%02x size %d\n",marker, itemlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Process a EXIF marker
|
||||||
|
Describes all the drivel that most digital cameras include...
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
|
||||||
|
{
|
||||||
|
m_exifinfo->FlashUsed = 0;
|
||||||
|
/* If it's from a digicam, and it used flash, it says so. */
|
||||||
|
m_exifinfo->Comments[0] = '\0'; /* Initial value - null string */
|
||||||
|
|
||||||
|
ExifImageWidth = 0;
|
||||||
|
|
||||||
|
{ /* Check the EXIF header component */
|
||||||
|
static const uint8_t ExifHeader[] = "Exif\0\0";
|
||||||
|
if (memcmp(CharBuf+0, ExifHeader,6)){
|
||||||
|
strcpy(m_szLastError,"Incorrect Exif header");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(CharBuf+6,"II",2) == 0){
|
||||||
|
MotorolaOrder = 0;
|
||||||
|
}else{
|
||||||
|
if (memcmp(CharBuf+6,"MM",2) == 0){
|
||||||
|
MotorolaOrder = 1;
|
||||||
|
}else{
|
||||||
|
strcpy(m_szLastError,"Invalid Exif alignment marker.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the next two values for correctness. */
|
||||||
|
if (Get16u(CharBuf+8) != 0x2a){
|
||||||
|
strcpy(m_szLastError,"Invalid Exif start (1)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FirstOffset = Get32u(CharBuf+10);
|
||||||
|
/* <Richard Collins>
|
||||||
|
if (FirstOffset < 8 || FirstOffset > 16){
|
||||||
|
// I used to ensure this was set to 8 (website I used indicated its 8)
|
||||||
|
// but PENTAX Optio 230 has it set differently, and uses it as offset. (Sept 11 2002)
|
||||||
|
strcpy(m_szLastError,"Suspicious offset of first IFD value");
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
uint8_t * LastExifRefd = CharBuf;
|
||||||
|
|
||||||
|
/* First directory starts 16 bytes in. Offsets start at 8 bytes in. */
|
||||||
|
if (!ProcessExifDir(CharBuf+14, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* <Richard Collins> give a chance for a second directory */
|
||||||
|
if (FirstOffset > 8) {
|
||||||
|
if (!ProcessExifDir(CharBuf+14+FirstOffset-8, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is how far the interesting (non thumbnail) part of the exif went. */
|
||||||
|
// int32_t ExifSettingsLength = LastExifRefd - CharBuf;
|
||||||
|
|
||||||
|
/* Compute the CCD width, in milimeters. */
|
||||||
|
if (m_exifinfo->FocalplaneXRes != 0){
|
||||||
|
m_exifinfo->CCDWidth = (float)(ExifImageWidth * m_exifinfo->FocalplaneUnits / m_exifinfo->FocalplaneXRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Get 16 bits motorola order (always) for jpeg header stuff.
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
int32_t CxImageJPG::CxExifInfo::Get16m(void * Short)
|
||||||
|
{
|
||||||
|
return (((uint8_t *)Short)[0] << 8) | ((uint8_t *)Short)[1];
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Convert a 16 bit unsigned value from file's native byte order
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
int32_t CxImageJPG::CxExifInfo::Get16u(void * Short)
|
||||||
|
{
|
||||||
|
if (MotorolaOrder){
|
||||||
|
return (((uint8_t *)Short)[0] << 8) | ((uint8_t *)Short)[1];
|
||||||
|
}else{
|
||||||
|
return (((uint8_t *)Short)[1] << 8) | ((uint8_t *)Short)[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Convert a 32 bit signed value from file's native byte order
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
int32_t CxImageJPG::CxExifInfo::Get32s(void * Long)
|
||||||
|
{
|
||||||
|
if (MotorolaOrder){
|
||||||
|
return ((( char *)Long)[0] << 24) | (((uint8_t *)Long)[1] << 16)
|
||||||
|
| (((uint8_t *)Long)[2] << 8 ) | (((uint8_t *)Long)[3] << 0 );
|
||||||
|
}else{
|
||||||
|
return ((( char *)Long)[3] << 24) | (((uint8_t *)Long)[2] << 16)
|
||||||
|
| (((uint8_t *)Long)[1] << 8 ) | (((uint8_t *)Long)[0] << 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Convert a 32 bit unsigned value from file's native byte order
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
uint32_t CxImageJPG::CxExifInfo::Get32u(void * Long)
|
||||||
|
{
|
||||||
|
return (uint32_t)Get32s(Long) & 0xffffffff;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* Describes format descriptor */
|
||||||
|
static const int32_t BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
|
||||||
|
#define NUM_FORMATS 12
|
||||||
|
|
||||||
|
#define FMT_BYTE 1
|
||||||
|
#define FMT_STRING 2
|
||||||
|
#define FMT_USHORT 3
|
||||||
|
#define FMT_ULONG 4
|
||||||
|
#define FMT_URATIONAL 5
|
||||||
|
#define FMT_SBYTE 6
|
||||||
|
#define FMT_UNDEFINED 7
|
||||||
|
#define FMT_SSHORT 8
|
||||||
|
#define FMT_SLONG 9
|
||||||
|
#define FMT_SRATIONAL 10
|
||||||
|
#define FMT_SINGLE 11
|
||||||
|
#define FMT_DOUBLE 12
|
||||||
|
|
||||||
|
/* Describes tag values */
|
||||||
|
|
||||||
|
#define TAG_EXIF_VERSION 0x9000
|
||||||
|
#define TAG_EXIF_OFFSET 0x8769
|
||||||
|
#define TAG_INTEROP_OFFSET 0xa005
|
||||||
|
|
||||||
|
#define TAG_MAKE 0x010F
|
||||||
|
#define TAG_MODEL 0x0110
|
||||||
|
|
||||||
|
#define TAG_ORIENTATION 0x0112
|
||||||
|
#define TAG_XRESOLUTION 0x011A
|
||||||
|
#define TAG_YRESOLUTION 0x011B
|
||||||
|
#define TAG_RESOLUTIONUNIT 0x0128
|
||||||
|
|
||||||
|
#define TAG_EXPOSURETIME 0x829A
|
||||||
|
#define TAG_FNUMBER 0x829D
|
||||||
|
|
||||||
|
#define TAG_SHUTTERSPEED 0x9201
|
||||||
|
#define TAG_APERTURE 0x9202
|
||||||
|
#define TAG_BRIGHTNESS 0x9203
|
||||||
|
#define TAG_MAXAPERTURE 0x9205
|
||||||
|
#define TAG_FOCALLENGTH 0x920A
|
||||||
|
|
||||||
|
#define TAG_DATETIME_ORIGINAL 0x9003
|
||||||
|
#define TAG_USERCOMMENT 0x9286
|
||||||
|
|
||||||
|
#define TAG_SUBJECT_DISTANCE 0x9206
|
||||||
|
#define TAG_FLASH 0x9209
|
||||||
|
|
||||||
|
#define TAG_FOCALPLANEXRES 0xa20E
|
||||||
|
#define TAG_FOCALPLANEYRES 0xa20F
|
||||||
|
#define TAG_FOCALPLANEUNITS 0xa210
|
||||||
|
#define TAG_EXIF_IMAGEWIDTH 0xA002
|
||||||
|
#define TAG_EXIF_IMAGELENGTH 0xA003
|
||||||
|
|
||||||
|
/* the following is added 05-jan-2001 vcs */
|
||||||
|
#define TAG_EXPOSURE_BIAS 0x9204
|
||||||
|
#define TAG_WHITEBALANCE 0x9208
|
||||||
|
#define TAG_METERING_MODE 0x9207
|
||||||
|
#define TAG_EXPOSURE_PROGRAM 0x8822
|
||||||
|
#define TAG_ISO_EQUIVALENT 0x8827
|
||||||
|
#define TAG_COMPRESSION_LEVEL 0x9102
|
||||||
|
|
||||||
|
#define TAG_THUMBNAIL_OFFSET 0x0201
|
||||||
|
#define TAG_THUMBNAIL_LENGTH 0x0202
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Process one of the nested EXIF directories.
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
bool CxImageJPG::CxExifInfo::ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength,
|
||||||
|
EXIFINFO * const m_exifinfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel)
|
||||||
|
{
|
||||||
|
int32_t de;
|
||||||
|
int32_t a;
|
||||||
|
int32_t NumDirEntries;
|
||||||
|
unsigned ThumbnailOffset = 0;
|
||||||
|
unsigned ThumbnailSize = 0;
|
||||||
|
|
||||||
|
if (NestingLevel > 4){
|
||||||
|
strcpy(m_szLastError,"Maximum directory nesting exceeded (corrupt exif header)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumDirEntries = Get16u(DirStart);
|
||||||
|
|
||||||
|
if ((DirStart+2+NumDirEntries*12) > (OffsetBase+ExifLength)){
|
||||||
|
strcpy(m_szLastError,"Illegally sized directory");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (de=0;de<NumDirEntries;de++){
|
||||||
|
int32_t Tag, Format, Components;
|
||||||
|
uint8_t * ValuePtr;
|
||||||
|
/* This actually can point to a variety of things; it must be
|
||||||
|
cast to other types when used. But we use it as a byte-by-byte
|
||||||
|
cursor, so we declare it as a pointer to a generic byte here.
|
||||||
|
*/
|
||||||
|
int32_t ByteCount;
|
||||||
|
uint8_t * DirEntry;
|
||||||
|
DirEntry = DirStart+2+12*de;
|
||||||
|
|
||||||
|
Tag = Get16u(DirEntry);
|
||||||
|
Format = Get16u(DirEntry+2);
|
||||||
|
Components = Get32u(DirEntry+4);
|
||||||
|
|
||||||
|
if ((Format-1) >= NUM_FORMATS) {
|
||||||
|
/* (-1) catches illegal zero case as unsigned underflows to positive large */
|
||||||
|
strcpy(m_szLastError,"Illegal format code in EXIF dir");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteCount = Components * BytesPerFormat[Format];
|
||||||
|
|
||||||
|
if (ByteCount > 4){
|
||||||
|
unsigned OffsetVal;
|
||||||
|
OffsetVal = Get32u(DirEntry+8);
|
||||||
|
/* If its bigger than 4 bytes, the dir entry contains an offset.*/
|
||||||
|
if (OffsetVal+ByteCount > ExifLength){
|
||||||
|
/* Bogus pointer offset and / or bytecount value */
|
||||||
|
strcpy(m_szLastError,"Illegal pointer offset value in EXIF.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ValuePtr = OffsetBase+OffsetVal;
|
||||||
|
}else{
|
||||||
|
/* 4 bytes or less and value is in the dir entry itself */
|
||||||
|
ValuePtr = DirEntry+8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*LastExifRefdP < ValuePtr+ByteCount){
|
||||||
|
/* Keep track of last byte in the exif header that was
|
||||||
|
actually referenced. That way, we know where the
|
||||||
|
discardable thumbnail data begins.
|
||||||
|
*/
|
||||||
|
*LastExifRefdP = ValuePtr+ByteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract useful components of tag */
|
||||||
|
switch(Tag){
|
||||||
|
|
||||||
|
case TAG_MAKE:
|
||||||
|
strncpy(m_exifinfo->CameraMake, (char*)ValuePtr, 31);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_MODEL:
|
||||||
|
strncpy(m_exifinfo->CameraModel, (char*)ValuePtr, 39);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_EXIF_VERSION:
|
||||||
|
strncpy(m_exifinfo->Version,(char*)ValuePtr, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_DATETIME_ORIGINAL:
|
||||||
|
strncpy(m_exifinfo->DateTime, (char*)ValuePtr, 19);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_USERCOMMENT:
|
||||||
|
// Olympus has this padded with trailing spaces. Remove these first.
|
||||||
|
for (a=ByteCount;;){
|
||||||
|
a--;
|
||||||
|
if (((char*)ValuePtr)[a] == ' '){
|
||||||
|
((char*)ValuePtr)[a] = '\0';
|
||||||
|
}else{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (a == 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the comment */
|
||||||
|
if (memcmp(ValuePtr, "ASCII",5) == 0){
|
||||||
|
for (a=5;a<10;a++){
|
||||||
|
char c;
|
||||||
|
c = ((char*)ValuePtr)[a];
|
||||||
|
if (c != '\0' && c != ' '){
|
||||||
|
strncpy(m_exifinfo->Comments, (char*)ValuePtr+a, 199);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
strncpy(m_exifinfo->Comments, (char*)ValuePtr, 199);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_FNUMBER:
|
||||||
|
/* Simplest way of expressing aperture, so I trust it the most.
|
||||||
|
(overwrite previously computd value if there is one)
|
||||||
|
*/
|
||||||
|
m_exifinfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_APERTURE:
|
||||||
|
case TAG_MAXAPERTURE:
|
||||||
|
/* More relevant info always comes earlier, so only
|
||||||
|
use this field if we don't have appropriate aperture
|
||||||
|
information yet.
|
||||||
|
*/
|
||||||
|
if (m_exifinfo->ApertureFNumber == 0){
|
||||||
|
m_exifinfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)*0.5);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_BRIGHTNESS:
|
||||||
|
m_exifinfo->Brightness = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_FOCALLENGTH:
|
||||||
|
/* Nice digital cameras actually save the focal length
|
||||||
|
as a function of how farthey are zoomed in.
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_exifinfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_SUBJECT_DISTANCE:
|
||||||
|
/* Inidcates the distacne the autofocus camera is focused to.
|
||||||
|
Tends to be less accurate as distance increases.
|
||||||
|
*/
|
||||||
|
m_exifinfo->Distance = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_EXPOSURETIME:
|
||||||
|
/* Simplest way of expressing exposure time, so I
|
||||||
|
trust it most. (overwrite previously computd value
|
||||||
|
if there is one)
|
||||||
|
*/
|
||||||
|
m_exifinfo->ExposureTime =
|
||||||
|
(float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_SHUTTERSPEED:
|
||||||
|
/* More complicated way of expressing exposure time,
|
||||||
|
so only use this value if we don't already have it
|
||||||
|
from somewhere else.
|
||||||
|
*/
|
||||||
|
if (m_exifinfo->ExposureTime == 0){
|
||||||
|
m_exifinfo->ExposureTime = (float)
|
||||||
|
(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_FLASH:
|
||||||
|
if ((int32_t)ConvertAnyFormat(ValuePtr, Format) & 7){
|
||||||
|
m_exifinfo->FlashUsed = 1;
|
||||||
|
}else{
|
||||||
|
m_exifinfo->FlashUsed = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_ORIENTATION:
|
||||||
|
m_exifinfo->Orientation = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
if (m_exifinfo->Orientation < 1 || m_exifinfo->Orientation > 8){
|
||||||
|
strcpy(m_szLastError,"Undefined rotation value");
|
||||||
|
m_exifinfo->Orientation = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_EXIF_IMAGELENGTH:
|
||||||
|
case TAG_EXIF_IMAGEWIDTH:
|
||||||
|
/* Use largest of height and width to deal with images
|
||||||
|
that have been rotated to portrait format.
|
||||||
|
*/
|
||||||
|
a = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
if (ExifImageWidth < a) ExifImageWidth = a;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_FOCALPLANEXRES:
|
||||||
|
m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_FOCALPLANEYRES:
|
||||||
|
m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_RESOLUTIONUNIT:
|
||||||
|
switch((int32_t)ConvertAnyFormat(ValuePtr, Format)){
|
||||||
|
case 1: m_exifinfo->ResolutionUnit = 1.0f; break; /* 1 inch */
|
||||||
|
case 2: m_exifinfo->ResolutionUnit = 1.0f; break;
|
||||||
|
case 3: m_exifinfo->ResolutionUnit = 0.3937007874f; break; /* 1 centimeter*/
|
||||||
|
case 4: m_exifinfo->ResolutionUnit = 0.03937007874f; break; /* 1 millimeter*/
|
||||||
|
case 5: m_exifinfo->ResolutionUnit = 0.00003937007874f; /* 1 micrometer*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_FOCALPLANEUNITS:
|
||||||
|
switch((int32_t)ConvertAnyFormat(ValuePtr, Format)){
|
||||||
|
case 1: m_exifinfo->FocalplaneUnits = 1.0f; break; /* 1 inch */
|
||||||
|
case 2: m_exifinfo->FocalplaneUnits = 1.0f; break;
|
||||||
|
case 3: m_exifinfo->FocalplaneUnits = 0.3937007874f; break; /* 1 centimeter*/
|
||||||
|
case 4: m_exifinfo->FocalplaneUnits = 0.03937007874f; break; /* 1 millimeter*/
|
||||||
|
case 5: m_exifinfo->FocalplaneUnits = 0.00003937007874f; /* 1 micrometer*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Remaining cases contributed by: Volker C. Schoech <schoech(at)gmx(dot)de>
|
||||||
|
|
||||||
|
case TAG_EXPOSURE_BIAS:
|
||||||
|
m_exifinfo->ExposureBias = (float) ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_WHITEBALANCE:
|
||||||
|
m_exifinfo->Whitebalance = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_METERING_MODE:
|
||||||
|
m_exifinfo->MeteringMode = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_EXPOSURE_PROGRAM:
|
||||||
|
m_exifinfo->ExposureProgram = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_ISO_EQUIVALENT:
|
||||||
|
m_exifinfo->ISOequivalent = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_COMPRESSION_LEVEL:
|
||||||
|
m_exifinfo->CompressionLevel = (int32_t)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_XRESOLUTION:
|
||||||
|
m_exifinfo->Xresolution = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
case TAG_YRESOLUTION:
|
||||||
|
m_exifinfo->Yresolution = (float)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_THUMBNAIL_OFFSET:
|
||||||
|
ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAG_THUMBNAIL_LENGTH:
|
||||||
|
ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
|
||||||
|
uint8_t * SubdirStart;
|
||||||
|
unsigned Offset = Get32u(ValuePtr);
|
||||||
|
if (Offset>8){
|
||||||
|
SubdirStart = OffsetBase + Offset;
|
||||||
|
if (SubdirStart < OffsetBase ||
|
||||||
|
SubdirStart > OffsetBase+ExifLength){
|
||||||
|
strcpy(m_szLastError,"Illegal subdirectory link");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
/* In addition to linking to subdirectories via exif tags,
|
||||||
|
there's also a potential link to another directory at the end
|
||||||
|
of each directory. This has got to be the result of a
|
||||||
|
committee!
|
||||||
|
*/
|
||||||
|
uint8_t * SubdirStart;
|
||||||
|
unsigned Offset;
|
||||||
|
Offset = Get16u(DirStart+2+12*NumDirEntries);
|
||||||
|
if (Offset){
|
||||||
|
SubdirStart = OffsetBase + Offset;
|
||||||
|
if (SubdirStart < OffsetBase
|
||||||
|
|| SubdirStart > OffsetBase+ExifLength){
|
||||||
|
strcpy(m_szLastError,"Illegal subdirectory link");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ThumbnailSize && ThumbnailOffset){
|
||||||
|
if (ThumbnailSize + ThumbnailOffset <= ExifLength){
|
||||||
|
/* The thumbnail pointer appears to be valid. Store it. */
|
||||||
|
m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset;
|
||||||
|
m_exifinfo->ThumbnailSize = ThumbnailSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
Evaluate number, be it int32_t, rational, or float from directory.
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int32_t Format)
|
||||||
|
{
|
||||||
|
double Value;
|
||||||
|
Value = 0;
|
||||||
|
|
||||||
|
switch(Format){
|
||||||
|
case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
|
||||||
|
case FMT_BYTE: Value = *(uint8_t *)ValuePtr; break;
|
||||||
|
|
||||||
|
case FMT_USHORT: Value = Get16u(ValuePtr); break;
|
||||||
|
case FMT_ULONG: Value = Get32u(ValuePtr); break;
|
||||||
|
|
||||||
|
case FMT_URATIONAL:
|
||||||
|
case FMT_SRATIONAL:
|
||||||
|
{
|
||||||
|
int32_t Num,Den;
|
||||||
|
Num = Get32s(ValuePtr);
|
||||||
|
Den = Get32s(4+(char *)ValuePtr);
|
||||||
|
if (Den == 0){
|
||||||
|
Value = 0;
|
||||||
|
}else{
|
||||||
|
Value = (double)Num/Den;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FMT_SSHORT: Value = (int16_t)Get16u(ValuePtr); break;
|
||||||
|
case FMT_SLONG: Value = Get32s(ValuePtr); break;
|
||||||
|
|
||||||
|
/* Not sure if this is correct (never seen float used in Exif format)
|
||||||
|
*/
|
||||||
|
case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break;
|
||||||
|
case FMT_DOUBLE: Value = *(double *)ValuePtr; break;
|
||||||
|
}
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageJPG::CxExifInfo::process_COM (const uint8_t * Data, int32_t length)
|
||||||
|
{
|
||||||
|
int32_t ch;
|
||||||
|
char Comment[MAX_COMMENT+1];
|
||||||
|
int32_t nch;
|
||||||
|
int32_t a;
|
||||||
|
|
||||||
|
nch = 0;
|
||||||
|
|
||||||
|
if (length > MAX_COMMENT) length = MAX_COMMENT; // Truncate if it won't fit in our structure.
|
||||||
|
|
||||||
|
for (a=2;a<length;a++){
|
||||||
|
ch = Data[a];
|
||||||
|
|
||||||
|
if (ch == '\r' && Data[a+1] == '\n') continue; // Remove cr followed by lf.
|
||||||
|
|
||||||
|
if (isprint(ch) || ch == '\n' || ch == '\t'){
|
||||||
|
Comment[nch++] = (char)ch;
|
||||||
|
}else{
|
||||||
|
Comment[nch++] = '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Comment[nch] = '\0'; // Null terminate
|
||||||
|
|
||||||
|
//if (ShowTags) printf("COM marker comment: %s\n",Comment);
|
||||||
|
|
||||||
|
strcpy(m_exifinfo->Comments,Comment);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageJPG::CxExifInfo::process_SOFn (const uint8_t * Data, int32_t marker)
|
||||||
|
{
|
||||||
|
int32_t data_precision, num_components;
|
||||||
|
|
||||||
|
data_precision = Data[2];
|
||||||
|
m_exifinfo->Height = Get16m((void*)(Data+3));
|
||||||
|
m_exifinfo->Width = Get16m((void*)(Data+5));
|
||||||
|
num_components = Data[7];
|
||||||
|
|
||||||
|
if (num_components == 3){
|
||||||
|
m_exifinfo->IsColor = 1;
|
||||||
|
}else{
|
||||||
|
m_exifinfo->IsColor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_exifinfo->Process = marker;
|
||||||
|
|
||||||
|
//if (ShowTags) printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
|
||||||
|
// ImageInfo.Width, ImageInfo.Height, num_components, data_precision);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* this will work only on a CxImageJPG object, if the image originally has valid EXIF data
|
||||||
|
\verbatim
|
||||||
|
CxImageJPG jpg;
|
||||||
|
CxIOFile in,out;
|
||||||
|
in.Open("D:\\exif_in.jpg","rb");
|
||||||
|
out.Open("D:\\exif_out.jpg","w+b");
|
||||||
|
jpg.Decode(&in);
|
||||||
|
if (jpg.IsValid()){
|
||||||
|
jpg.RotateLeft();
|
||||||
|
jpg.Encode(&out);
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
*/
|
||||||
|
bool CxImageJPG::CxExifInfo::EncodeExif(CxFile * hFile)
|
||||||
|
{
|
||||||
|
int32_t a;
|
||||||
|
|
||||||
|
if (FindSection(M_SOS)==NULL){
|
||||||
|
strcpy(m_szLastError,"Can't write exif : didn't read all");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial static jpeg marker.
|
||||||
|
hFile->PutC(0xff);
|
||||||
|
hFile->PutC(0xd8);
|
||||||
|
|
||||||
|
if (Sections[0].Type != M_EXIF && Sections[0].Type != M_JFIF){
|
||||||
|
// The image must start with an exif or jfif marker. If we threw those away, create one.
|
||||||
|
static uint8_t JfifHead[18] = {
|
||||||
|
0xff, M_JFIF,
|
||||||
|
0x00, 0x10, 'J' , 'F' , 'I' , 'F' , 0x00, 0x01,
|
||||||
|
0x01, 0x01, 0x01, 0x2C, 0x01, 0x2C, 0x00, 0x00
|
||||||
|
};
|
||||||
|
hFile->Write(JfifHead, 18, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write all the misc sections
|
||||||
|
for (a=0;a<SectionsRead-1;a++){
|
||||||
|
hFile->PutC(0xff);
|
||||||
|
hFile->PutC((uint8_t)(Sections[a].Type));
|
||||||
|
hFile->Write(Sections[a].Data, Sections[a].Size, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the remaining image data.
|
||||||
|
hFile->Write(Sections[a].Data, Sections[a].Size, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageJPG::CxExifInfo::DiscardAllButExif()
|
||||||
|
{
|
||||||
|
Section_t ExifKeeper;
|
||||||
|
Section_t CommentKeeper;
|
||||||
|
int32_t a;
|
||||||
|
|
||||||
|
memset(&ExifKeeper, 0, sizeof(ExifKeeper));
|
||||||
|
memset(&CommentKeeper, 0, sizeof(ExifKeeper));
|
||||||
|
|
||||||
|
for (a=0;a<SectionsRead;a++){
|
||||||
|
if (Sections[a].Type == M_EXIF && ExifKeeper.Type == 0){
|
||||||
|
ExifKeeper = Sections[a];
|
||||||
|
}else if (Sections[a].Type == M_COM && CommentKeeper.Type == 0){
|
||||||
|
CommentKeeper = Sections[a];
|
||||||
|
}else{
|
||||||
|
free(Sections[a].Data);
|
||||||
|
Sections[a].Data = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionsRead = 0;
|
||||||
|
if (ExifKeeper.Type){
|
||||||
|
Sections[SectionsRead++] = ExifKeeper;
|
||||||
|
}
|
||||||
|
if (CommentKeeper.Type){
|
||||||
|
Sections[SectionsRead++] = CommentKeeper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void* CxImageJPG::CxExifInfo::FindSection(int32_t SectionType)
|
||||||
|
{
|
||||||
|
int32_t a;
|
||||||
|
for (a=0;a<SectionsRead-1;a++){
|
||||||
|
if (Sections[a].Type == SectionType){
|
||||||
|
return &Sections[a];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Could not be found.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGEJPG_SUPPORT_EXIF
|
||||||
537
Raw2Bmp_MFC/include/ximage.cpp
Normal file
537
Raw2Bmp_MFC/include/ximage.cpp
Normal file
@@ -0,0 +1,537 @@
|
|||||||
|
// ximage.cpp : main implementation file
|
||||||
|
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CxImage
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Initialize the internal structures
|
||||||
|
*/
|
||||||
|
void CxImage::Startup(uint32_t imagetype)
|
||||||
|
{
|
||||||
|
//init pointers
|
||||||
|
pDib = pSelection = pAlpha = NULL;
|
||||||
|
ppLayers = ppFrames = NULL;
|
||||||
|
//init structures
|
||||||
|
memset(&head,0,sizeof(BITMAPINFOHEADER));
|
||||||
|
memset(&info,0,sizeof(CXIMAGEINFO));
|
||||||
|
//init default attributes
|
||||||
|
info.dwType = imagetype;
|
||||||
|
info.fQuality = 90.0f;
|
||||||
|
info.nAlphaMax = 255;
|
||||||
|
info.nBkgndIndex = -1;
|
||||||
|
info.bEnabled = true;
|
||||||
|
info.nJpegScale = 1;
|
||||||
|
SetXDPI(CXIMAGE_DEFAULT_DPI);
|
||||||
|
SetYDPI(CXIMAGE_DEFAULT_DPI);
|
||||||
|
|
||||||
|
int16_t test = 1;
|
||||||
|
info.bLittleEndianHost = (*((char *) &test) == 1);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Empty image constructor
|
||||||
|
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
|
||||||
|
*/
|
||||||
|
CxImage::CxImage(uint32_t imagetype)
|
||||||
|
{
|
||||||
|
Startup(imagetype);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Call this function to destroy image pixels, alpha channel, selection and sub layers.
|
||||||
|
* - Attributes are not erased, but IsValid returns false.
|
||||||
|
*
|
||||||
|
* \return true if everything is freed, false if the image is a Ghost
|
||||||
|
*/
|
||||||
|
bool CxImage::Destroy()
|
||||||
|
{
|
||||||
|
//free this only if it's valid and it's not a ghost
|
||||||
|
if (info.pGhost==NULL){
|
||||||
|
if (ppLayers) {
|
||||||
|
for(int32_t n=0; n<info.nNumLayers;n++){ delete ppLayers[n]; }
|
||||||
|
delete [] ppLayers; ppLayers=0; info.nNumLayers = 0;
|
||||||
|
}
|
||||||
|
if (pSelection) {free(pSelection); pSelection=0;}
|
||||||
|
if (pAlpha) {free(pAlpha); pAlpha=0;}
|
||||||
|
if (pDib) {free(pDib); pDib=0;}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::DestroyFrames()
|
||||||
|
{
|
||||||
|
if (info.pGhost==NULL) {
|
||||||
|
if (ppFrames) {
|
||||||
|
for (int32_t n=0; n<info.nNumFrames; n++) { delete ppFrames[n]; }
|
||||||
|
delete [] ppFrames; ppFrames = NULL; info.nNumFrames = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sized image constructor
|
||||||
|
* \param dwWidth: width
|
||||||
|
* \param dwHeight: height
|
||||||
|
* \param wBpp: bit per pixel, can be 1, 4, 8, 24
|
||||||
|
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
|
||||||
|
*/
|
||||||
|
CxImage::CxImage(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype)
|
||||||
|
{
|
||||||
|
Startup(imagetype);
|
||||||
|
Create(dwWidth,dwHeight,wBpp,imagetype);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* image constructor from existing source
|
||||||
|
* \param src: source image.
|
||||||
|
* \param copypixels: copy the pixels from the source image into the new image.
|
||||||
|
* \param copyselection: copy the selection from source
|
||||||
|
* \param copyalpha: copy the alpha channel from source
|
||||||
|
* \sa Copy
|
||||||
|
*/
|
||||||
|
CxImage::CxImage(const CxImage &src, bool copypixels, bool copyselection, bool copyalpha)
|
||||||
|
{
|
||||||
|
Startup(src.GetType());
|
||||||
|
Copy(src,copypixels,copyselection,copyalpha);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Copies the image from an exsisting source
|
||||||
|
* \param src: source image.
|
||||||
|
* \param copypixels: copy the pixels from the source image into the new image.
|
||||||
|
* \param copyselection: copy the selection from source
|
||||||
|
* \param copyalpha: copy the alpha channel from source
|
||||||
|
*/
|
||||||
|
void CxImage::Copy(const CxImage &src, bool copypixels, bool copyselection, bool copyalpha)
|
||||||
|
{
|
||||||
|
// if the source is a ghost, the copy is still a ghost
|
||||||
|
if (src.info.pGhost){
|
||||||
|
Ghost(&src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//copy the attributes
|
||||||
|
memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
|
||||||
|
memcpy(&head,&src.head,sizeof(BITMAPINFOHEADER)); // [andy] - fix for bitmap header DPI
|
||||||
|
//rebuild the image
|
||||||
|
Create(src.GetWidth(),src.GetHeight(),src.GetBpp(),src.GetType());
|
||||||
|
//copy the pixels and the palette, or at least copy the palette only.
|
||||||
|
if (copypixels && pDib && src.pDib) memcpy(pDib,src.pDib,GetSize());
|
||||||
|
else SetPalette(src.GetPalette());
|
||||||
|
int32_t nSize = head.biWidth * head.biHeight;
|
||||||
|
//copy the selection
|
||||||
|
if (copyselection && src.pSelection){
|
||||||
|
if (pSelection) free(pSelection);
|
||||||
|
pSelection = (uint8_t*)malloc(nSize);
|
||||||
|
memcpy(pSelection,src.pSelection,nSize);
|
||||||
|
}
|
||||||
|
//copy the alpha channel
|
||||||
|
if (copyalpha && src.pAlpha){
|
||||||
|
if (pAlpha) free(pAlpha);
|
||||||
|
pAlpha = (uint8_t*)malloc(nSize);
|
||||||
|
memcpy(pAlpha,src.pAlpha,nSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Copies the image attributes from an existing image.
|
||||||
|
* - Works only on an empty image, and the image will be still empty.
|
||||||
|
* - <b> Use it before Create() </b>
|
||||||
|
*/
|
||||||
|
void CxImage::CopyInfo(const CxImage &src)
|
||||||
|
{
|
||||||
|
if (pDib==NULL) memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa Copy
|
||||||
|
*/
|
||||||
|
CxImage& CxImage::operator = (const CxImage& isrc)
|
||||||
|
{
|
||||||
|
if (this != &isrc) Copy(isrc);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Initializes or rebuilds the image.
|
||||||
|
* \param dwWidth: width
|
||||||
|
* \param dwHeight: height
|
||||||
|
* \param wBpp: bit per pixel, can be 1, 4, 8, 24
|
||||||
|
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
|
||||||
|
* \return pointer to the internal pDib object; NULL if an error occurs.
|
||||||
|
*/
|
||||||
|
void* CxImage::Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype)
|
||||||
|
{
|
||||||
|
// destroy the existing image (if any)
|
||||||
|
if (!Destroy())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// prevent further actions if width or height are not vaild <Balabasnia>
|
||||||
|
if ((dwWidth == 0) || (dwHeight == 0)){
|
||||||
|
strcpy(info.szLastError,"CxImage::Create : width and height must be greater than zero");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure bits per pixel is valid
|
||||||
|
if (wBpp <= 1) wBpp = 1;
|
||||||
|
else if (wBpp <= 4) wBpp = 4;
|
||||||
|
else if (wBpp <= 8) wBpp = 8;
|
||||||
|
else wBpp = 24;
|
||||||
|
|
||||||
|
// limit memory requirements
|
||||||
|
if ((((float)dwWidth*(float)dwHeight*(float)wBpp)/8.0f) > (float)CXIMAGE_MAX_MEMORY)
|
||||||
|
{
|
||||||
|
strcpy(info.szLastError,"CXIMAGE_MAX_MEMORY exceeded");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the correct bpp value
|
||||||
|
switch (wBpp){
|
||||||
|
case 1:
|
||||||
|
head.biClrUsed = 2; break;
|
||||||
|
case 4:
|
||||||
|
head.biClrUsed = 16; break;
|
||||||
|
case 8:
|
||||||
|
head.biClrUsed = 256; break;
|
||||||
|
default:
|
||||||
|
head.biClrUsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set the common image informations
|
||||||
|
info.dwEffWidth = ((((wBpp * dwWidth) + 31) / 32) * 4);
|
||||||
|
info.dwType = imagetype;
|
||||||
|
|
||||||
|
// initialize BITMAPINFOHEADER
|
||||||
|
head.biSize = sizeof(BITMAPINFOHEADER); //<ralphw>
|
||||||
|
head.biWidth = dwWidth; // fill in width from parameter
|
||||||
|
head.biHeight = dwHeight; // fill in height from parameter
|
||||||
|
head.biPlanes = 1; // must be 1
|
||||||
|
head.biBitCount = (uint16_t)wBpp; // from parameter
|
||||||
|
head.biCompression = BI_RGB;
|
||||||
|
head.biSizeImage = info.dwEffWidth * dwHeight;
|
||||||
|
// head.biXPelsPerMeter = 0; See SetXDPI
|
||||||
|
// head.biYPelsPerMeter = 0; See SetYDPI
|
||||||
|
// head.biClrImportant = 0; See SetClrImportant
|
||||||
|
|
||||||
|
pDib = malloc(GetSize()); // alloc memory block to store our bitmap
|
||||||
|
if (!pDib){
|
||||||
|
strcpy(info.szLastError,"CxImage::Create can't allocate memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//clear the palette
|
||||||
|
RGBQUAD* pal=GetPalette();
|
||||||
|
if (pal) memset(pal,0,GetPaletteSize());
|
||||||
|
//Destroy the existing selection
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
if (pSelection) SelectionDelete();
|
||||||
|
#endif //CXIMAGE_SUPPORT_SELECTION
|
||||||
|
//Destroy the existing alpha channel
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pAlpha) AlphaDelete();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
// use our bitmap info structure to fill in first part of
|
||||||
|
// our DIB with the BITMAPINFOHEADER
|
||||||
|
BITMAPINFOHEADER* lpbi;
|
||||||
|
lpbi = (BITMAPINFOHEADER*)(pDib);
|
||||||
|
*lpbi = head;
|
||||||
|
|
||||||
|
info.pImage=GetBits();
|
||||||
|
|
||||||
|
return pDib; //return handle to the DIB
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return pointer to the image pixels. <b> USE CAREFULLY </b>
|
||||||
|
*/
|
||||||
|
uint8_t* CxImage::GetBits(uint32_t row)
|
||||||
|
{
|
||||||
|
if (pDib){
|
||||||
|
if (row) {
|
||||||
|
if (row<(uint32_t)head.biHeight){
|
||||||
|
return ((uint8_t*)pDib + *(uint32_t*)pDib + GetPaletteSize() + (info.dwEffWidth * row));
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ((uint8_t*)pDib + *(uint32_t*)pDib + GetPaletteSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return the size in bytes of the internal pDib object
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetSize()
|
||||||
|
{
|
||||||
|
return head.biSize + head.biSizeImage + GetPaletteSize();
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the coordinates are inside the image
|
||||||
|
* \return true if x and y are both inside the image
|
||||||
|
*/
|
||||||
|
bool CxImage::IsInside(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
return (0<=y && y<head.biHeight && 0<=x && x<head.biWidth);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the image bits to the specified value
|
||||||
|
* - for indexed images, the output color is set by the palette entries.
|
||||||
|
* - for RGB images, the output color is a shade of gray.
|
||||||
|
*/
|
||||||
|
void CxImage::Clear(uint8_t bval)
|
||||||
|
{
|
||||||
|
if (pDib == 0) return;
|
||||||
|
|
||||||
|
if (GetBpp() == 1){
|
||||||
|
if (bval > 0) bval = 255;
|
||||||
|
}
|
||||||
|
if (GetBpp() == 4){
|
||||||
|
bval = (uint8_t)(17*(0x0F & bval));
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(info.pImage,bval,head.biSizeImage);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Transfers the image from an existing source image. The source becomes empty.
|
||||||
|
* \return true if everything is ok
|
||||||
|
*/
|
||||||
|
bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/)
|
||||||
|
{
|
||||||
|
if (!Destroy())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
memcpy(&head,&from.head,sizeof(BITMAPINFOHEADER));
|
||||||
|
memcpy(&info,&from.info,sizeof(CXIMAGEINFO));
|
||||||
|
|
||||||
|
pDib = from.pDib;
|
||||||
|
pSelection = from.pSelection;
|
||||||
|
pAlpha = from.pAlpha;
|
||||||
|
ppLayers = from.ppLayers;
|
||||||
|
|
||||||
|
memset(&from.head,0,sizeof(BITMAPINFOHEADER));
|
||||||
|
memset(&from.info,0,sizeof(CXIMAGEINFO));
|
||||||
|
from.pDib = from.pSelection = from.pAlpha = NULL;
|
||||||
|
from.ppLayers = NULL;
|
||||||
|
|
||||||
|
if (bTransferFrames){
|
||||||
|
DestroyFrames();
|
||||||
|
ppFrames = from.ppFrames;
|
||||||
|
from.ppFrames = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* (this) points to the same pDib owned by (*from), the image remains in (*from)
|
||||||
|
* but (this) has the access to the pixels. <b>Use carefully !!!</b>
|
||||||
|
*/
|
||||||
|
void CxImage::Ghost(const CxImage *from)
|
||||||
|
{
|
||||||
|
if (from){
|
||||||
|
memcpy(&head,&from->head,sizeof(BITMAPINFOHEADER));
|
||||||
|
memcpy(&info,&from->info,sizeof(CXIMAGEINFO));
|
||||||
|
pDib = from->pDib;
|
||||||
|
pSelection = from->pSelection;
|
||||||
|
pAlpha = from->pAlpha;
|
||||||
|
ppLayers = from->ppLayers;
|
||||||
|
ppFrames = from->ppFrames;
|
||||||
|
info.pGhost=(CxImage *)from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* turns a 16 or 32 bit bitfield image into a RGB image
|
||||||
|
*/
|
||||||
|
void CxImage::Bitfield2RGB(uint8_t *src, uint32_t redmask, uint32_t greenmask, uint32_t bluemask, uint8_t bpp)
|
||||||
|
{
|
||||||
|
switch (bpp){
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
uint32_t ns[3]={0,0,0};
|
||||||
|
// compute the number of shift for each mask
|
||||||
|
for (int32_t i=0;i<16;i++){
|
||||||
|
if ((redmask>>i)&0x01) ns[0]++;
|
||||||
|
if ((greenmask>>i)&0x01) ns[1]++;
|
||||||
|
if ((bluemask>>i)&0x01) ns[2]++;
|
||||||
|
}
|
||||||
|
ns[1]+=ns[0]; ns[2]+=ns[1]; ns[0]=8-ns[0]; ns[1]-=8; ns[2]-=8;
|
||||||
|
// dword aligned width for 16 bit image
|
||||||
|
int32_t effwidth2=(((head.biWidth + 1) / 2) * 4);
|
||||||
|
uint16_t w;
|
||||||
|
int32_t y2,y3,x2,x3;
|
||||||
|
uint8_t *p=info.pImage;
|
||||||
|
// scan the buffer in reverse direction to avoid reallocations
|
||||||
|
for (int32_t y=head.biHeight-1; y>=0; y--){
|
||||||
|
y2=effwidth2*y;
|
||||||
|
y3=info.dwEffWidth*y;
|
||||||
|
for (int32_t x=head.biWidth-1; x>=0; x--){
|
||||||
|
x2 = 2*x+y2;
|
||||||
|
x3 = 3*x+y3;
|
||||||
|
w = (uint16_t)(src[x2]+256*src[1+x2]);
|
||||||
|
p[ x3]=(uint8_t)((w & bluemask)<<ns[0]);
|
||||||
|
p[1+x3]=(uint8_t)((w & greenmask)>>ns[1]);
|
||||||
|
p[2+x3]=(uint8_t)((w & redmask)>>ns[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 32:
|
||||||
|
{
|
||||||
|
uint32_t ns[3]={0,0,0};
|
||||||
|
// compute the number of shift for each mask
|
||||||
|
for (int32_t i=8;i<32;i+=8){
|
||||||
|
if (redmask>>i) ns[0]++;
|
||||||
|
if (greenmask>>i) ns[1]++;
|
||||||
|
if (bluemask>>i) ns[2]++;
|
||||||
|
}
|
||||||
|
// dword aligned width for 32 bit image
|
||||||
|
int32_t effwidth4 = head.biWidth * 4;
|
||||||
|
int32_t y4,y3,x4,x3;
|
||||||
|
uint8_t *p=info.pImage;
|
||||||
|
// scan the buffer in reverse direction to avoid reallocations
|
||||||
|
for (int32_t y=head.biHeight-1; y>=0; y--){
|
||||||
|
y4=effwidth4*y;
|
||||||
|
y3=info.dwEffWidth*y;
|
||||||
|
for (int32_t x=head.biWidth-1; x>=0; x--){
|
||||||
|
x4 = 4*x+y4;
|
||||||
|
x3 = 3*x+y3;
|
||||||
|
p[ x3]=src[ns[2]+x4];
|
||||||
|
p[1+x3]=src[ns[1]+x4];
|
||||||
|
p[2+x3]=src[ns[0]+x4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Creates an image from a generic buffer
|
||||||
|
* \param pArray: source memory buffer
|
||||||
|
* \param dwWidth: image width
|
||||||
|
* \param dwHeight: image height
|
||||||
|
* \param dwBitsperpixel: can be 1,4,8,24,32
|
||||||
|
* \param dwBytesperline: line alignment, in bytes, for a single row stored in pArray
|
||||||
|
* \param bFlipImage: tune this parameter if the image is upsidedown
|
||||||
|
* \return true if everything is ok
|
||||||
|
*/
|
||||||
|
bool CxImage::CreateFromArray(uint8_t* pArray,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage)
|
||||||
|
{
|
||||||
|
if (pArray==NULL) return false;
|
||||||
|
if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)||
|
||||||
|
(dwBitsperpixel==24)||(dwBitsperpixel==32))) return false;
|
||||||
|
|
||||||
|
if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false;
|
||||||
|
|
||||||
|
if (dwBitsperpixel<24) SetGrayPalette();
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (dwBitsperpixel==32) AlphaCreate();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
uint8_t *dst,*src;
|
||||||
|
|
||||||
|
for (uint32_t y = 0; y<dwHeight; y++) {
|
||||||
|
dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
|
||||||
|
src = pArray + y * dwBytesperline;
|
||||||
|
if (dwBitsperpixel==32){
|
||||||
|
for(uint32_t x=0;x<dwWidth;x++){
|
||||||
|
*dst++=src[0];
|
||||||
|
*dst++=src[1];
|
||||||
|
*dst++=src[2];
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
AlphaSet(x,(bFlipImage?(dwHeight-1-y):y),src[3]);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
src+=4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa CreateFromArray
|
||||||
|
*/
|
||||||
|
bool CxImage::CreateFromMatrix(uint8_t** ppMatrix,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage)
|
||||||
|
{
|
||||||
|
if (ppMatrix==NULL) return false;
|
||||||
|
if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)||
|
||||||
|
(dwBitsperpixel==24)||(dwBitsperpixel==32))) return false;
|
||||||
|
|
||||||
|
if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false;
|
||||||
|
|
||||||
|
if (dwBitsperpixel<24) SetGrayPalette();
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (dwBitsperpixel==32) AlphaCreate();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
uint8_t *dst,*src;
|
||||||
|
|
||||||
|
for (uint32_t y = 0; y<dwHeight; y++) {
|
||||||
|
dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
|
||||||
|
src = ppMatrix[y];
|
||||||
|
if (src){
|
||||||
|
if (dwBitsperpixel==32){
|
||||||
|
for(uint32_t x=0;x<dwWidth;x++){
|
||||||
|
*dst++=src[0];
|
||||||
|
*dst++=src[1];
|
||||||
|
*dst++=src[2];
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
AlphaSet(x,(bFlipImage?(dwHeight-1-y):y),src[3]);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
src+=4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return lightness difference between elem1 and elem2
|
||||||
|
*/
|
||||||
|
int32_t CxImage::CompareColors(const void *elem1, const void *elem2)
|
||||||
|
{
|
||||||
|
RGBQUAD* c1 = (RGBQUAD*)elem1;
|
||||||
|
RGBQUAD* c2 = (RGBQUAD*)elem2;
|
||||||
|
|
||||||
|
int32_t g1 = (int32_t)RGB2GRAY(c1->rgbRed,c1->rgbGreen,c1->rgbBlue);
|
||||||
|
int32_t g2 = (int32_t)RGB2GRAY(c2->rgbRed,c2->rgbGreen,c2->rgbBlue);
|
||||||
|
|
||||||
|
return (g1-g2);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* simply calls "if (memblock) free(memblock);".
|
||||||
|
* Useful when calling Encode for a memory buffer,
|
||||||
|
* from a DLL compiled with different memory management options.
|
||||||
|
* CxImage::FreeMemory will use the same memory environment used by Encode.
|
||||||
|
* \author [livecn]
|
||||||
|
*/
|
||||||
|
void CxImage::FreeMemory(void* memblock)
|
||||||
|
{
|
||||||
|
if (memblock)
|
||||||
|
free(memblock);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//EOF
|
||||||
807
Raw2Bmp_MFC/include/ximage.h
Normal file
807
Raw2Bmp_MFC/include/ximage.h
Normal file
@@ -0,0 +1,807 @@
|
|||||||
|
/*
|
||||||
|
* File: ximage.h
|
||||||
|
* Purpose: General Purpose Image Class
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
|
||||||
|
|
||||||
|
CxImage version 7.0.1 07/Jan/2011
|
||||||
|
|
||||||
|
CxImage : Copyright (C) 2001 - 2010, Davide Pizzolato
|
||||||
|
|
||||||
|
Original CImage and CImageIterator implementation are:
|
||||||
|
Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx)
|
||||||
|
|
||||||
|
Covered code is provided under this license on an "as is" basis, without warranty
|
||||||
|
of any kind, either expressed or implied, including, without limitation, warranties
|
||||||
|
that the covered code is free of defects, merchantable, fit for a particular purpose
|
||||||
|
or non-infringing. The entire risk as to the quality and performance of the covered
|
||||||
|
code is with you. Should any covered code prove defective in any respect, you (not
|
||||||
|
the initial developer or any other contributor) assume the cost of any necessary
|
||||||
|
servicing, repair or correction. This disclaimer of warranty constitutes an essential
|
||||||
|
part of this license. No use of any covered code is authorized hereunder except under
|
||||||
|
this disclaimer.
|
||||||
|
|
||||||
|
Permission is hereby granted to use, copy, modify, and distribute this
|
||||||
|
source code, or portions hereof, for any purpose, including commercial applications,
|
||||||
|
freely and without fee, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Other information about CxImage, and the latest version, can be found at the
|
||||||
|
CxImage home page: http://www.xdp.it/cximage/
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#if !defined(__CXIMAGE_H)
|
||||||
|
#define __CXIMAGE_H
|
||||||
|
|
||||||
|
#if _MSC_VER > 1000
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LINUX
|
||||||
|
#define _XOPEN_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include "xfile.h"
|
||||||
|
#include "xiofile.h"
|
||||||
|
#include "xmemfile.h"
|
||||||
|
#include "ximadef.h" //<vho> adjust some #define
|
||||||
|
|
||||||
|
/* see "ximacfg.h" for CxImage configuration options */
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CxImage formats enumerator
|
||||||
|
enum ENUM_CXIMAGE_FORMATS{
|
||||||
|
CXIMAGE_FORMAT_UNKNOWN = 0,
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
CXIMAGE_FORMAT_BMP = 1,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_GIF
|
||||||
|
CXIMAGE_FORMAT_GIF = 2,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
CXIMAGE_FORMAT_JPG = 3,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
CXIMAGE_FORMAT_PNG = 4,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
CXIMAGE_FORMAT_ICO = 5,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
CXIMAGE_FORMAT_TIF = 6,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
CXIMAGE_FORMAT_TGA = 7,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
CXIMAGE_FORMAT_PCX = 8,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
CXIMAGE_FORMAT_WBMP = 9,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WMF
|
||||||
|
CXIMAGE_FORMAT_WMF = 10,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
CXIMAGE_FORMAT_JP2 = 11,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
CXIMAGE_FORMAT_JPC = 12,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
CXIMAGE_FORMAT_PGX = 13,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
CXIMAGE_FORMAT_PNM = 14,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
CXIMAGE_FORMAT_RAS = 15,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
CXIMAGE_FORMAT_JBG = 16,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
CXIMAGE_FORMAT_MNG = 17,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
CXIMAGE_FORMAT_SKA = 18,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
CXIMAGE_FORMAT_RAW = 19,
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PSD
|
||||||
|
CXIMAGE_FORMAT_PSD = 20,
|
||||||
|
#endif
|
||||||
|
CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG +
|
||||||
|
CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO +
|
||||||
|
CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX +
|
||||||
|
CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF +
|
||||||
|
CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC +
|
||||||
|
CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS +
|
||||||
|
CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + CXIMAGE_SUPPORT_PSD + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_EXIF
|
||||||
|
|
||||||
|
#define MAX_COMMENT 255
|
||||||
|
#define MAX_SECTIONS 20
|
||||||
|
|
||||||
|
typedef struct tag_ExifInfo {
|
||||||
|
char Version [5];
|
||||||
|
char CameraMake [32];
|
||||||
|
char CameraModel [40];
|
||||||
|
char DateTime [20];
|
||||||
|
int32_t Height, Width;
|
||||||
|
int32_t Orientation;
|
||||||
|
int32_t IsColor;
|
||||||
|
int32_t Process;
|
||||||
|
int32_t FlashUsed;
|
||||||
|
float FocalLength;
|
||||||
|
float ExposureTime;
|
||||||
|
float ApertureFNumber;
|
||||||
|
float Distance;
|
||||||
|
float CCDWidth;
|
||||||
|
float ExposureBias;
|
||||||
|
int32_t Whitebalance;
|
||||||
|
int32_t MeteringMode;
|
||||||
|
int32_t ExposureProgram;
|
||||||
|
int32_t ISOequivalent;
|
||||||
|
int32_t CompressionLevel;
|
||||||
|
float FocalplaneXRes;
|
||||||
|
float FocalplaneYRes;
|
||||||
|
float FocalplaneUnits;
|
||||||
|
float Xresolution;
|
||||||
|
float Yresolution;
|
||||||
|
float ResolutionUnit;
|
||||||
|
float Brightness;
|
||||||
|
char Comments[MAX_COMMENT+1];
|
||||||
|
|
||||||
|
uint8_t * ThumbnailPointer; /* Pointer at the thumbnail */
|
||||||
|
unsigned ThumbnailSize; /* Size of thumbnail. */
|
||||||
|
|
||||||
|
bool IsExif;
|
||||||
|
} EXIFINFO;
|
||||||
|
|
||||||
|
#endif //CXIMAGE_SUPPORT_EXIF
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CxImage class
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
class DLL_EXP CxImage
|
||||||
|
{
|
||||||
|
//extensible information collector
|
||||||
|
typedef struct tagCxImageInfo {
|
||||||
|
uint32_t dwEffWidth; ///< uint32_t aligned scan line width
|
||||||
|
uint8_t* pImage; ///< THE IMAGE BITS
|
||||||
|
CxImage* pGhost; ///< if this is a ghost, pGhost points to the body
|
||||||
|
CxImage* pParent; ///< if this is a layer, pParent points to the body
|
||||||
|
uint32_t dwType; ///< original image format
|
||||||
|
char szLastError[256]; ///< debugging
|
||||||
|
int32_t nProgress; ///< monitor
|
||||||
|
int32_t nEscape; ///< escape
|
||||||
|
int32_t nBkgndIndex; ///< used for GIF, PNG, MNG
|
||||||
|
RGBQUAD nBkgndColor; ///< used for RGB transparency
|
||||||
|
float fQuality; ///< used for JPEG, JPEG2000 (0.0f ... 100.0f)
|
||||||
|
uint8_t nJpegScale; ///< used for JPEG [ignacio]
|
||||||
|
int32_t nFrame; ///< used for TIF, GIF, MNG : actual frame
|
||||||
|
int32_t nNumFrames; ///< used for TIF, GIF, MNG : total number of frames
|
||||||
|
uint32_t dwFrameDelay; ///< used for GIF, MNG
|
||||||
|
int32_t xDPI; ///< horizontal resolution
|
||||||
|
int32_t yDPI; ///< vertical resolution
|
||||||
|
RECT rSelectionBox; ///< bounding rectangle
|
||||||
|
uint8_t nAlphaMax; ///< max opacity (fade)
|
||||||
|
bool bAlphaPaletteEnabled; ///< true if alpha values in the palette are enabled.
|
||||||
|
bool bEnabled; ///< enables the painting functions
|
||||||
|
int32_t xOffset;
|
||||||
|
int32_t yOffset;
|
||||||
|
uint32_t dwCodecOpt[CMAX_IMAGE_FORMATS]; ///< for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg
|
||||||
|
RGBQUAD last_c; ///< for GetNearestIndex optimization
|
||||||
|
uint8_t last_c_index;
|
||||||
|
bool last_c_isvalid;
|
||||||
|
int32_t nNumLayers;
|
||||||
|
uint32_t dwFlags; ///< 0x??00000 = reserved, 0x00??0000 = blend mode, 0x0000???? = layer id - user flags
|
||||||
|
uint8_t dispmeth;
|
||||||
|
bool bGetAllFrames;
|
||||||
|
bool bLittleEndianHost;
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_EXIF
|
||||||
|
EXIFINFO ExifInfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} CXIMAGEINFO;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//public structures
|
||||||
|
struct rgb_color { uint8_t r,g,b; };
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
// <VATI> text placement data
|
||||||
|
// members must be initialized with the InitTextInfo(&this) function.
|
||||||
|
typedef struct tagCxTextInfo
|
||||||
|
{
|
||||||
|
#if defined (_WIN32_WCE)
|
||||||
|
TCHAR text[256]; ///< text for windows CE
|
||||||
|
#else
|
||||||
|
TCHAR text[4096]; ///< text (char -> TCHAR for UNICODE [Cesar M])
|
||||||
|
#endif
|
||||||
|
LOGFONT lfont; ///< font and codepage data
|
||||||
|
COLORREF fcolor; ///< foreground color
|
||||||
|
int32_t align; ///< DT_CENTER, DT_RIGHT, DT_LEFT aligment for multiline text
|
||||||
|
uint8_t smooth; ///< text smoothing option. Default is false.
|
||||||
|
uint8_t opaque; ///< text has background or hasn't. Default is true.
|
||||||
|
///< data for background (ignored if .opaque==FALSE)
|
||||||
|
COLORREF bcolor; ///< background color
|
||||||
|
float b_opacity; ///< opacity value for background between 0.0-1.0 Default is 0. (opaque)
|
||||||
|
uint8_t b_outline; ///< outline width for background (zero: no outline)
|
||||||
|
uint8_t b_round; ///< rounding radius for background rectangle. % of the height, between 0-50. Default is 10.
|
||||||
|
///< (backgr. always has a frame: width = 3 pixel + 10% of height by default.)
|
||||||
|
} CXTEXTINFO;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** \addtogroup Constructors */ //@{
|
||||||
|
CxImage(uint32_t imagetype = 0);
|
||||||
|
CxImage(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0);
|
||||||
|
CxImage(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
CxImage(const TCHAR * filename, uint32_t imagetype); // For UNICODE support: char -> TCHAR
|
||||||
|
CxImage(FILE * stream, uint32_t imagetype);
|
||||||
|
CxImage(CxFile * stream, uint32_t imagetype);
|
||||||
|
CxImage(uint8_t * buffer, uint32_t size, uint32_t imagetype);
|
||||||
|
#endif
|
||||||
|
virtual ~CxImage() { DestroyFrames(); Destroy(); };
|
||||||
|
CxImage& operator = (const CxImage&);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** \addtogroup Initialization */ //@{
|
||||||
|
void* Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0);
|
||||||
|
bool Destroy();
|
||||||
|
bool DestroyFrames();
|
||||||
|
void Clear(uint8_t bval=0);
|
||||||
|
void Copy(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
|
||||||
|
bool Transfer(CxImage &from, bool bTransferFrames = true);
|
||||||
|
bool CreateFromArray(uint8_t* pArray,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage);
|
||||||
|
bool CreateFromMatrix(uint8_t** ppMatrix,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage);
|
||||||
|
void FreeMemory(void* memblock);
|
||||||
|
|
||||||
|
uint32_t Dump(uint8_t * dst);
|
||||||
|
uint32_t UnDump(const uint8_t * src);
|
||||||
|
uint32_t DumpSize();
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** \addtogroup Attributes */ //@{
|
||||||
|
int32_t GetSize();
|
||||||
|
uint8_t* GetBits(uint32_t row = 0);
|
||||||
|
uint8_t GetColorType();
|
||||||
|
void* GetDIB() const;
|
||||||
|
uint32_t GetHeight() const;
|
||||||
|
uint32_t GetWidth() const;
|
||||||
|
uint32_t GetEffWidth() const;
|
||||||
|
uint32_t GetNumColors() const;
|
||||||
|
uint16_t GetBpp() const;
|
||||||
|
uint32_t GetType() const;
|
||||||
|
const char* GetLastError();
|
||||||
|
static const TCHAR* GetVersion();
|
||||||
|
static const float GetVersionNumber();
|
||||||
|
|
||||||
|
uint32_t GetFrameDelay() const;
|
||||||
|
void SetFrameDelay(uint32_t d);
|
||||||
|
|
||||||
|
void GetOffset(int32_t *x,int32_t *y);
|
||||||
|
void SetOffset(int32_t x,int32_t y);
|
||||||
|
|
||||||
|
uint8_t GetJpegQuality() const;
|
||||||
|
void SetJpegQuality(uint8_t q);
|
||||||
|
float GetJpegQualityF() const;
|
||||||
|
void SetJpegQualityF(float q);
|
||||||
|
|
||||||
|
uint8_t GetJpegScale() const;
|
||||||
|
void SetJpegScale(uint8_t q);
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_EXIF
|
||||||
|
EXIFINFO *GetExifInfo() {return &info.ExifInfo;};
|
||||||
|
bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t imageType);
|
||||||
|
#if CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
bool RotateExif(int32_t orientation = 0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t GetXDPI() const;
|
||||||
|
int32_t GetYDPI() const;
|
||||||
|
void SetXDPI(int32_t dpi);
|
||||||
|
void SetYDPI(int32_t dpi);
|
||||||
|
|
||||||
|
uint32_t GetClrImportant() const;
|
||||||
|
void SetClrImportant(uint32_t ncolors = 0);
|
||||||
|
|
||||||
|
int32_t GetProgress() const;
|
||||||
|
int32_t GetEscape() const;
|
||||||
|
void SetProgress(int32_t p);
|
||||||
|
void SetEscape(int32_t i);
|
||||||
|
|
||||||
|
int32_t GetTransIndex() const;
|
||||||
|
RGBQUAD GetTransColor();
|
||||||
|
void SetTransIndex(int32_t idx);
|
||||||
|
void SetTransColor(RGBQUAD rgb);
|
||||||
|
bool IsTransparent() const;
|
||||||
|
|
||||||
|
uint32_t GetCodecOption(uint32_t imagetype = 0);
|
||||||
|
bool SetCodecOption(uint32_t opt, uint32_t imagetype = 0);
|
||||||
|
|
||||||
|
uint32_t GetFlags() const;
|
||||||
|
void SetFlags(uint32_t flags, bool bLockReservedFlags = true);
|
||||||
|
|
||||||
|
uint8_t GetDisposalMethod() const;
|
||||||
|
void SetDisposalMethod(uint8_t dm);
|
||||||
|
|
||||||
|
bool SetType(uint32_t type);
|
||||||
|
|
||||||
|
static uint32_t GetNumTypes();
|
||||||
|
static uint32_t GetTypeIdFromName(const TCHAR* ext);
|
||||||
|
static uint32_t GetTypeIdFromIndex(const uint32_t index);
|
||||||
|
static uint32_t GetTypeIndexFromId(const uint32_t id);
|
||||||
|
|
||||||
|
bool GetRetreiveAllFrames() const;
|
||||||
|
void SetRetreiveAllFrames(bool flag);
|
||||||
|
CxImage * GetFrame(int32_t nFrame) const;
|
||||||
|
|
||||||
|
//void* GetUserData() const {return info.pUserData;}
|
||||||
|
//void SetUserData(void* pUserData) {info.pUserData = pUserData;}
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** \addtogroup Palette
|
||||||
|
* These functions have no effects on RGB images and in this case the returned value is always 0.
|
||||||
|
* @{ */
|
||||||
|
bool IsGrayScale();
|
||||||
|
bool IsIndexed() const;
|
||||||
|
bool IsSamePalette(CxImage &img, bool bCheckAlpha = true);
|
||||||
|
uint32_t GetPaletteSize();
|
||||||
|
RGBQUAD* GetPalette() const;
|
||||||
|
RGBQUAD GetPaletteColor(uint8_t idx);
|
||||||
|
bool GetPaletteColor(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b);
|
||||||
|
uint8_t GetNearestIndex(RGBQUAD c);
|
||||||
|
void BlendPalette(COLORREF cr,int32_t perc);
|
||||||
|
void SetGrayPalette();
|
||||||
|
void SetPalette(uint32_t n, uint8_t *r, uint8_t *g, uint8_t *b);
|
||||||
|
void SetPalette(RGBQUAD* pPal,uint32_t nColors=256);
|
||||||
|
void SetPalette(rgb_color *rgb,uint32_t nColors=256);
|
||||||
|
void SetPaletteColor(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t alpha=0);
|
||||||
|
void SetPaletteColor(uint8_t idx, RGBQUAD c);
|
||||||
|
void SetPaletteColor(uint8_t idx, COLORREF cr);
|
||||||
|
void SwapIndex(uint8_t idx1, uint8_t idx2);
|
||||||
|
void SwapRGB2BGR();
|
||||||
|
void SetStdPalette();
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** \addtogroup Pixel */ //@{
|
||||||
|
bool IsInside(int32_t x, int32_t y);
|
||||||
|
bool IsTransparent(int32_t x,int32_t y);
|
||||||
|
bool GetTransparentMask(CxImage* iDst = 0);
|
||||||
|
RGBQUAD GetPixelColor(int32_t x,int32_t y, bool bGetAlpha = true);
|
||||||
|
uint8_t GetPixelIndex(int32_t x,int32_t y);
|
||||||
|
uint8_t GetPixelGray(int32_t x, int32_t y);
|
||||||
|
void SetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha = false);
|
||||||
|
void SetPixelColor(int32_t x,int32_t y,COLORREF cr);
|
||||||
|
void SetPixelIndex(int32_t x,int32_t y,uint8_t i);
|
||||||
|
void DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, RGBQUAD color, bool bSetAlpha=false);
|
||||||
|
void DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, COLORREF cr);
|
||||||
|
void BlendPixelColor(int32_t x,int32_t y,RGBQUAD c, float blend, bool bSetAlpha = false);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
uint8_t BlindGetPixelIndex(const int32_t x,const int32_t y);
|
||||||
|
RGBQUAD BlindGetPixelColor(const int32_t x,const int32_t y, bool bGetAlpha = true);
|
||||||
|
void *BlindGetPixelPointer(const int32_t x,const int32_t y);
|
||||||
|
void BlindSetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha = false);
|
||||||
|
void BlindSetPixelIndex(int32_t x,int32_t y,uint8_t i);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_INTERPOLATION
|
||||||
|
/** \addtogroup Interpolation */ //@{
|
||||||
|
//overflow methods:
|
||||||
|
enum OverflowMethod {
|
||||||
|
OM_COLOR=1,
|
||||||
|
OM_BACKGROUND=2,
|
||||||
|
OM_TRANSPARENT=3,
|
||||||
|
OM_WRAP=4,
|
||||||
|
OM_REPEAT=5,
|
||||||
|
OM_MIRROR=6
|
||||||
|
};
|
||||||
|
void OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod);
|
||||||
|
void OverflowCoordinates(int32_t &x, int32_t &y, OverflowMethod const ofMethod);
|
||||||
|
RGBQUAD GetPixelColorWithOverflow(int32_t x, int32_t y, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
|
||||||
|
//interpolation methods:
|
||||||
|
enum InterpolationMethod {
|
||||||
|
IM_NEAREST_NEIGHBOUR=1,
|
||||||
|
IM_BILINEAR =2,
|
||||||
|
IM_BSPLINE =3,
|
||||||
|
IM_BICUBIC =4,
|
||||||
|
IM_BICUBIC2 =5,
|
||||||
|
IM_LANCZOS =6,
|
||||||
|
IM_BOX =7,
|
||||||
|
IM_HERMITE =8,
|
||||||
|
IM_HAMMING =9,
|
||||||
|
IM_SINC =10,
|
||||||
|
IM_BLACKMAN =11,
|
||||||
|
IM_BESSEL =12,
|
||||||
|
IM_GAUSSIAN =13,
|
||||||
|
IM_QUADRATIC =14,
|
||||||
|
IM_MITCHELL =15,
|
||||||
|
IM_CATROM =16,
|
||||||
|
IM_HANNING =17,
|
||||||
|
IM_POWER =18
|
||||||
|
};
|
||||||
|
RGBQUAD GetPixelColorInterpolated(float x,float y, InterpolationMethod const inMethod=IM_BILINEAR, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
|
||||||
|
RGBQUAD GetAreaColorInterpolated(float const xc, float const yc, float const w, float const h, InterpolationMethod const inMethod, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
void AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** \addtogroup Kernels */ //@{
|
||||||
|
public:
|
||||||
|
static float KernelBSpline(const float x);
|
||||||
|
static float KernelLinear(const float t);
|
||||||
|
static float KernelCubic(const float t);
|
||||||
|
static float KernelGeneralizedCubic(const float t, const float a=-1);
|
||||||
|
static float KernelLanczosSinc(const float t, const float r = 3);
|
||||||
|
static float KernelBox(const float x);
|
||||||
|
static float KernelHermite(const float x);
|
||||||
|
static float KernelHamming(const float x);
|
||||||
|
static float KernelSinc(const float x);
|
||||||
|
static float KernelBlackman(const float x);
|
||||||
|
static float KernelBessel_J1(const float x);
|
||||||
|
static float KernelBessel_P1(const float x);
|
||||||
|
static float KernelBessel_Q1(const float x);
|
||||||
|
static float KernelBessel_Order1(float x);
|
||||||
|
static float KernelBessel(const float x);
|
||||||
|
static float KernelGaussian(const float x);
|
||||||
|
static float KernelQuadratic(const float x);
|
||||||
|
static float KernelMitchell(const float x);
|
||||||
|
static float KernelCatrom(const float x);
|
||||||
|
static float KernelHanning(const float x);
|
||||||
|
static float KernelPower(const float x, const float a = 2);
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_INTERPOLATION
|
||||||
|
|
||||||
|
/** \addtogroup Painting */ //@{
|
||||||
|
#if CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
int32_t Blt(HDC pDC, int32_t x=0, int32_t y=0);
|
||||||
|
HBITMAP Draw2HBITMAP(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy, RECT* pClipRect, bool bSmooth);
|
||||||
|
HBITMAP MakeBitmap(HDC hdc = NULL, bool bTransparency = false);
|
||||||
|
HICON MakeIcon(HDC hdc = NULL, bool bTransparency = false);
|
||||||
|
HANDLE CopyToHandle();
|
||||||
|
bool CreateFromHANDLE(HANDLE hMem); //Windows objects (clipboard)
|
||||||
|
bool CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0, bool bTransparency = false); //Windows resource
|
||||||
|
bool CreateFromHICON(HICON hico, bool bTransparency = false);
|
||||||
|
int32_t Draw(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1, RECT* pClipRect = 0, bool bSmooth = false, bool bFlipY = false);
|
||||||
|
int32_t Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false, bool bFlipY = false);
|
||||||
|
int32_t Stretch(HDC hdc, int32_t xoffset, int32_t yoffset, int32_t xsize, int32_t ysize, uint32_t dwRop = SRCCOPY);
|
||||||
|
int32_t Stretch(HDC hdc, const RECT& rect, uint32_t dwRop = SRCCOPY);
|
||||||
|
int32_t Tile(HDC hdc, RECT *rc);
|
||||||
|
int32_t Draw2(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1);
|
||||||
|
int32_t Draw2(HDC hdc, const RECT& rect);
|
||||||
|
//int32_t DrawString(HDC hdc, int32_t x, int32_t y, const char* text, RGBQUAD color, const char* font, int32_t lSize=0, int32_t lWeight=400, uint8_t bItalic=0, uint8_t bUnderline=0, bool bSetAlpha=false);
|
||||||
|
int32_t DrawString(HDC hdc, int32_t x, int32_t y, const TCHAR* text, RGBQUAD color, const TCHAR* font, int32_t lSize=0, int32_t lWeight=400, uint8_t bItalic=0, uint8_t bUnderline=0, bool bSetAlpha=false);
|
||||||
|
// <VATI> extensions
|
||||||
|
int32_t DrawStringEx(HDC hdc, int32_t x, int32_t y, CXTEXTINFO *pTextType, bool bSetAlpha=false );
|
||||||
|
void InitTextInfo( CXTEXTINFO *txt );
|
||||||
|
protected:
|
||||||
|
bool IsHBITMAPAlphaValid( HBITMAP hbmp );
|
||||||
|
public:
|
||||||
|
#endif //CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
//@}
|
||||||
|
|
||||||
|
// file operations
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
/** \addtogroup Decode */ //@{
|
||||||
|
#ifdef WIN32
|
||||||
|
//bool Load(LPCWSTR filename, uint32_t imagetype=0);
|
||||||
|
bool LoadResource(HRSRC hRes, uint32_t imagetype, HMODULE hModule=NULL);
|
||||||
|
#endif
|
||||||
|
// For UNICODE support: char -> TCHAR
|
||||||
|
bool Load(const TCHAR* filename, uint32_t imagetype=0);
|
||||||
|
//bool Load(const char * filename, uint32_t imagetype=0);
|
||||||
|
bool Decode(FILE * hFile, uint32_t imagetype);
|
||||||
|
bool Decode(CxFile * hFile, uint32_t imagetype);
|
||||||
|
bool Decode(uint8_t * buffer, uint32_t size, uint32_t imagetype);
|
||||||
|
|
||||||
|
bool CheckFormat(CxFile * hFile, uint32_t imagetype = 0);
|
||||||
|
bool CheckFormat(uint8_t * buffer, uint32_t size, uint32_t imagetype = 0);
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
bool EncodeSafeCheck(CxFile *hFile);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** \addtogroup Encode */ //@{
|
||||||
|
#ifdef WIN32
|
||||||
|
//bool Save(LPCWSTR filename, uint32_t imagetype=0);
|
||||||
|
#endif
|
||||||
|
// For UNICODE support: char -> TCHAR
|
||||||
|
bool Save(const TCHAR* filename, uint32_t imagetype);
|
||||||
|
//bool Save(const char * filename, uint32_t imagetype=0);
|
||||||
|
bool Encode(FILE * hFile, uint32_t imagetype);
|
||||||
|
bool Encode(CxFile * hFile, uint32_t imagetype);
|
||||||
|
bool Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype);
|
||||||
|
bool Encode(FILE *hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype);
|
||||||
|
bool Encode(uint8_t * &buffer, int32_t &size, uint32_t imagetype);
|
||||||
|
|
||||||
|
bool Encode2RGBA(CxFile *hFile, bool bFlipY = false);
|
||||||
|
bool Encode2RGBA(uint8_t * &buffer, int32_t &size, bool bFlipY = false);
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
/** \addtogroup Attributes */ //@{
|
||||||
|
//misc.
|
||||||
|
bool IsValid() const;
|
||||||
|
bool IsEnabled() const;
|
||||||
|
void Enable(bool enable=true);
|
||||||
|
|
||||||
|
// frame operations
|
||||||
|
int32_t GetNumFrames() const;
|
||||||
|
int32_t GetFrame() const;
|
||||||
|
void SetFrame(int32_t nFrame);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
|
||||||
|
/** \addtogroup BasicTransformations */ //@{
|
||||||
|
bool GrayScale();
|
||||||
|
bool Flip(bool bFlipSelection = false, bool bFlipAlpha = true);
|
||||||
|
bool Mirror(bool bMirrorSelection = false, bool bMirrorAlpha = true);
|
||||||
|
bool Negative();
|
||||||
|
bool RotateLeft(CxImage* iDst = NULL);
|
||||||
|
bool RotateRight(CxImage* iDst = NULL);
|
||||||
|
bool IncreaseBpp(uint32_t nbit);
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
/** \addtogroup Transformations */ //@{
|
||||||
|
// image operations
|
||||||
|
bool Rotate(float angle, CxImage* iDst = NULL);
|
||||||
|
bool Rotate2(float angle, CxImage *iDst = NULL, InterpolationMethod inMethod=IM_BILINEAR,
|
||||||
|
OverflowMethod ofMethod=OM_BACKGROUND, RGBQUAD *replColor=0,
|
||||||
|
bool const optimizeRightAngles=true, bool const bKeepOriginalSize=false);
|
||||||
|
bool Rotate180(CxImage* iDst = NULL);
|
||||||
|
bool Resample(int32_t newx, int32_t newy, int32_t mode = 1, CxImage* iDst = NULL);
|
||||||
|
bool Resample2(int32_t newx, int32_t newy, InterpolationMethod const inMethod=IM_BICUBIC2,
|
||||||
|
OverflowMethod const ofMethod=OM_REPEAT, CxImage* const iDst = NULL,
|
||||||
|
bool const disableAveraging=false);
|
||||||
|
bool DecreaseBpp(uint32_t nbit, bool errordiffusion, RGBQUAD* ppal = 0, uint32_t clrimportant = 0);
|
||||||
|
bool Dither(int32_t method = 0);
|
||||||
|
bool Crop(int32_t left, int32_t top, int32_t right, int32_t bottom, CxImage* iDst = NULL);
|
||||||
|
bool Crop(const RECT& rect, CxImage* iDst = NULL);
|
||||||
|
bool CropRotatedRectangle( int32_t topx, int32_t topy, int32_t width, int32_t height, float angle, CxImage* iDst = NULL);
|
||||||
|
bool Skew(float xgain, float ygain, int32_t xpivot=0, int32_t ypivot=0, bool bEnableInterpolation = false);
|
||||||
|
bool Expand(int32_t left, int32_t top, int32_t right, int32_t bottom, RGBQUAD canvascolor, CxImage* iDst = 0);
|
||||||
|
bool Expand(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst = 0);
|
||||||
|
bool Thumbnail(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst = 0);
|
||||||
|
bool CircleTransform(int32_t type,int32_t rmax=0,float Koeff=1.0f);
|
||||||
|
bool QIShrink(int32_t newx, int32_t newy, CxImage* const iDst = NULL, bool bChangeBpp = false);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_DSP
|
||||||
|
/** \addtogroup DSP */ //@{
|
||||||
|
bool Contour();
|
||||||
|
bool HistogramStretch(int32_t method = 0, double threshold = 0);
|
||||||
|
bool HistogramEqualize();
|
||||||
|
bool HistogramNormalize();
|
||||||
|
bool HistogramRoot();
|
||||||
|
bool HistogramLog();
|
||||||
|
int32_t Histogram(int32_t* red, int32_t* green = 0, int32_t* blue = 0, int32_t* gray = 0, int32_t colorspace = 0);
|
||||||
|
bool Jitter(int32_t radius=2);
|
||||||
|
bool Repair(float radius = 0.25f, int32_t niterations = 1, int32_t colorspace = 0);
|
||||||
|
bool Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, int32_t colorspace = 0);
|
||||||
|
bool FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag, int32_t direction = 1, bool bForceFFT = true, bool bMagnitude = true);
|
||||||
|
bool Noise(int32_t level);
|
||||||
|
bool Median(int32_t Ksize=3);
|
||||||
|
bool Gamma(float gamma);
|
||||||
|
bool GammaRGB(float gammaR, float gammaG, float gammaB);
|
||||||
|
bool ShiftRGB(int32_t r, int32_t g, int32_t b);
|
||||||
|
bool Threshold(uint8_t level);
|
||||||
|
bool Threshold(CxImage* pThresholdMask);
|
||||||
|
bool Threshold2(uint8_t level, bool bDirection, RGBQUAD nBkgndColor, bool bSetAlpha = false);
|
||||||
|
bool Colorize(uint8_t hue, uint8_t sat, float blend = 1.0f);
|
||||||
|
bool Light(int32_t brightness, int32_t contrast = 0);
|
||||||
|
float Mean();
|
||||||
|
bool Filter(int32_t* kernel, int32_t Ksize, int32_t Kfactor, int32_t Koffset);
|
||||||
|
bool Erode(int32_t Ksize=2);
|
||||||
|
bool Dilate(int32_t Ksize=2);
|
||||||
|
bool Edge(int32_t Ksize=2);
|
||||||
|
void HuePalette(float correction=1);
|
||||||
|
enum ImageOpType { OpAdd, OpAnd, OpXor, OpOr, OpMask, OpSrcCopy, OpDstCopy, OpSub, OpSrcBlend, OpScreen, OpAvg, OpBlendAlpha };
|
||||||
|
void Mix(CxImage & imgsrc2, ImageOpType op, int32_t lXOffset = 0, int32_t lYOffset = 0, bool bMixAlpha = false);
|
||||||
|
void MixFrom(CxImage & imagesrc2, int32_t lXOffset, int32_t lYOffset);
|
||||||
|
bool UnsharpMask(float radius = 5.0f, float amount = 0.5f, int32_t threshold = 0);
|
||||||
|
bool Lut(uint8_t* pLut);
|
||||||
|
bool Lut(uint8_t* pLutR, uint8_t* pLutG, uint8_t* pLutB, uint8_t* pLutA = 0);
|
||||||
|
bool GaussianBlur(float radius = 1.0f, CxImage* iDst = 0);
|
||||||
|
bool TextBlur(uint8_t threshold = 100, uint8_t decay = 2, uint8_t max_depth = 5, bool bBlurHorizontal = true, bool bBlurVertical = true, CxImage* iDst = 0);
|
||||||
|
bool SelectiveBlur(float radius = 1.0f, uint8_t threshold = 25, CxImage* iDst = 0);
|
||||||
|
bool Solarize(uint8_t level = 128, bool bLinkedChannels = true);
|
||||||
|
bool FloodFill(const int32_t xStart, const int32_t yStart, const RGBQUAD cFillColor, const uint8_t tolerance = 0,
|
||||||
|
uint8_t nOpacity = 255, const bool bSelectFilledArea = false, const uint8_t nSelectionLevel = 255);
|
||||||
|
bool Saturate(const int32_t saturation, const int32_t colorspace = 1);
|
||||||
|
bool ConvertColorSpace(const int32_t dstColorSpace, const int32_t srcColorSpace);
|
||||||
|
int32_t OptimalThreshold(int32_t method = 0, RECT * pBox = 0, CxImage* pContrastMask = 0);
|
||||||
|
bool AdaptiveThreshold(int32_t method = 0, int32_t nBoxSize = 64, CxImage* pContrastMask = 0, int32_t nBias = 0, float fGlobalLocalBalance = 0.5f);
|
||||||
|
bool RedEyeRemove(float strength = 0.8f);
|
||||||
|
bool Trace(RGBQUAD color_target, RGBQUAD color_trace);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
bool IsPowerof2(int32_t x);
|
||||||
|
bool FFT(int32_t dir,int32_t m,double *x,double *y);
|
||||||
|
bool DFT(int32_t dir,int32_t m,double *x1,double *y1,double *x2,double *y2);
|
||||||
|
bool RepairChannel(CxImage *ch, float radius);
|
||||||
|
// <nipper>
|
||||||
|
int32_t gen_convolve_matrix (float radius, float **cmatrix_p);
|
||||||
|
float* gen_lookup_table (float *cmatrix, int32_t cmatrix_length);
|
||||||
|
void blur_line (float *ctable, float *cmatrix, int32_t cmatrix_length, uint8_t* cur_col, uint8_t* dest_col, int32_t y, int32_t bytes);
|
||||||
|
void blur_text (uint8_t threshold, uint8_t decay, uint8_t max_depth, CxImage* iSrc, CxImage* iDst, uint8_t bytes);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** \addtogroup ColorSpace */ //@{
|
||||||
|
bool SplitRGB(CxImage* r,CxImage* g,CxImage* b);
|
||||||
|
bool SplitYUV(CxImage* y,CxImage* u,CxImage* v);
|
||||||
|
bool SplitHSL(CxImage* h,CxImage* s,CxImage* l);
|
||||||
|
bool SplitYIQ(CxImage* y,CxImage* i,CxImage* q);
|
||||||
|
bool SplitXYZ(CxImage* x,CxImage* y,CxImage* z);
|
||||||
|
bool SplitCMYK(CxImage* c,CxImage* m,CxImage* y,CxImage* k);
|
||||||
|
static RGBQUAD HSLtoRGB(COLORREF cHSLColor);
|
||||||
|
static RGBQUAD RGBtoHSL(RGBQUAD lRGBColor);
|
||||||
|
static RGBQUAD HSLtoRGB(RGBQUAD lHSLColor);
|
||||||
|
static RGBQUAD YUVtoRGB(RGBQUAD lYUVColor);
|
||||||
|
static RGBQUAD RGBtoYUV(RGBQUAD lRGBColor);
|
||||||
|
static RGBQUAD YIQtoRGB(RGBQUAD lYIQColor);
|
||||||
|
static RGBQUAD RGBtoYIQ(RGBQUAD lRGBColor);
|
||||||
|
static RGBQUAD XYZtoRGB(RGBQUAD lXYZColor);
|
||||||
|
static RGBQUAD RGBtoXYZ(RGBQUAD lRGBColor);
|
||||||
|
#endif //CXIMAGE_SUPPORT_DSP
|
||||||
|
static RGBQUAD RGBtoRGBQUAD(COLORREF cr);
|
||||||
|
static COLORREF RGBQUADtoRGB (RGBQUAD c);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/** \addtogroup Selection */ //@{
|
||||||
|
bool SelectionIsValid();
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
bool SelectionClear(uint8_t level = 0);
|
||||||
|
bool SelectionCreate();
|
||||||
|
bool SelectionDelete();
|
||||||
|
bool SelectionInvert();
|
||||||
|
bool SelectionMirror();
|
||||||
|
bool SelectionFlip();
|
||||||
|
bool SelectionAddRect(RECT r, uint8_t level = 255);
|
||||||
|
bool SelectionAddEllipse(RECT r, uint8_t level = 255);
|
||||||
|
bool SelectionAddPolygon(POINT *points, int32_t npoints, uint8_t level = 255);
|
||||||
|
bool SelectionAddColor(RGBQUAD c, uint8_t level = 255);
|
||||||
|
bool SelectionAddPixel(int32_t x, int32_t y, uint8_t level = 255);
|
||||||
|
bool SelectionCopy(CxImage &from);
|
||||||
|
bool SelectionIsInside(int32_t x, int32_t y);
|
||||||
|
void SelectionGetBox(RECT& r);
|
||||||
|
bool SelectionToHRGN(HRGN& region);
|
||||||
|
bool SelectionSplit(CxImage *dest);
|
||||||
|
uint8_t SelectionGet(const int32_t x,const int32_t y);
|
||||||
|
bool SelectionSet(CxImage &from);
|
||||||
|
void SelectionRebuildBox();
|
||||||
|
uint8_t* SelectionGetPointer(const int32_t x = 0,const int32_t y = 0);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
bool BlindSelectionIsInside(int32_t x, int32_t y);
|
||||||
|
uint8_t BlindSelectionGet(const int32_t x,const int32_t y);
|
||||||
|
void SelectionSet(const int32_t x,const int32_t y,const uint8_t level);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
#endif //CXIMAGE_SUPPORT_SELECTION
|
||||||
|
//@}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
/** \addtogroup Alpha */ //@{
|
||||||
|
void AlphaClear();
|
||||||
|
bool AlphaCreate();
|
||||||
|
void AlphaDelete();
|
||||||
|
void AlphaInvert();
|
||||||
|
bool AlphaMirror();
|
||||||
|
bool AlphaFlip();
|
||||||
|
bool AlphaCopy(CxImage &from);
|
||||||
|
bool AlphaSplit(CxImage *dest);
|
||||||
|
void AlphaStrip();
|
||||||
|
void AlphaSet(uint8_t level);
|
||||||
|
bool AlphaSet(CxImage &from);
|
||||||
|
void AlphaSet(const int32_t x,const int32_t y,const uint8_t level);
|
||||||
|
uint8_t AlphaGet(const int32_t x,const int32_t y);
|
||||||
|
uint8_t AlphaGetMax() const;
|
||||||
|
void AlphaSetMax(uint8_t nAlphaMax);
|
||||||
|
bool AlphaIsValid();
|
||||||
|
uint8_t* AlphaGetPointer(const int32_t x = 0,const int32_t y = 0);
|
||||||
|
bool AlphaFromTransparency();
|
||||||
|
|
||||||
|
void AlphaPaletteClear();
|
||||||
|
void AlphaPaletteEnable(bool enable=true);
|
||||||
|
bool AlphaPaletteIsEnabled();
|
||||||
|
bool AlphaPaletteIsValid();
|
||||||
|
bool AlphaPaletteSplit(CxImage *dest);
|
||||||
|
//@}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
uint8_t BlindAlphaGet(const int32_t x,const int32_t y);
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
public:
|
||||||
|
#if CXIMAGE_SUPPORT_LAYERS
|
||||||
|
/** \addtogroup Layers */ //@{
|
||||||
|
bool LayerCreate(int32_t position = -1);
|
||||||
|
bool LayerDelete(int32_t position = -1);
|
||||||
|
void LayerDeleteAll();
|
||||||
|
CxImage* GetLayer(int32_t position);
|
||||||
|
CxImage* GetParent() const;
|
||||||
|
int32_t GetNumLayers() const;
|
||||||
|
int32_t LayerDrawAll(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1, RECT* pClipRect = 0, bool bSmooth = false);
|
||||||
|
int32_t LayerDrawAll(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false);
|
||||||
|
//@}
|
||||||
|
#endif //CXIMAGE_SUPPORT_LAYERS
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** \addtogroup Protected */ //@{
|
||||||
|
void Startup(uint32_t imagetype = 0);
|
||||||
|
void CopyInfo(const CxImage &src);
|
||||||
|
void Ghost(const CxImage *src);
|
||||||
|
void RGBtoBGR(uint8_t *buffer, int32_t length);
|
||||||
|
static float HueToRGB(float n1,float n2, float hue);
|
||||||
|
void Bitfield2RGB(uint8_t *src, uint32_t redmask, uint32_t greenmask, uint32_t bluemask, uint8_t bpp);
|
||||||
|
static int32_t CompareColors(const void *elem1, const void *elem2);
|
||||||
|
int16_t m_ntohs(const int16_t word);
|
||||||
|
int32_t m_ntohl(const int32_t dword);
|
||||||
|
void bihtoh(BITMAPINFOHEADER* bih);
|
||||||
|
|
||||||
|
void* pDib; //contains the header, the palette, the pixels
|
||||||
|
BITMAPINFOHEADER head; //standard header
|
||||||
|
CXIMAGEINFO info; //extended information
|
||||||
|
uint8_t* pSelection; //selected region
|
||||||
|
uint8_t* pAlpha; //alpha channel
|
||||||
|
CxImage** ppLayers; //generic layers
|
||||||
|
CxImage** ppFrames;
|
||||||
|
//@}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // !defined(__CXIMAGE_H)
|
||||||
1683
Raw2Bmp_MFC/include/ximagif.cpp
Normal file
1683
Raw2Bmp_MFC/include/ximagif.cpp
Normal file
File diff suppressed because it is too large
Load Diff
244
Raw2Bmp_MFC/include/ximagif.h
Normal file
244
Raw2Bmp_MFC/include/ximagif.h
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* File: ximagif.h
|
||||||
|
* Purpose: GIF Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageGIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
|
||||||
|
*
|
||||||
|
* original CImageGIF and CImageIterator implementation are:
|
||||||
|
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
|
||||||
|
*
|
||||||
|
* 6/15/97 Randy Spann: Added GIF87a writing support
|
||||||
|
* R.Spann@ConnRiver.net
|
||||||
|
*
|
||||||
|
* DECODE.C - An LZW decoder for GIF
|
||||||
|
* Copyright (C) 1987, by Steven A. Bennett
|
||||||
|
* Copyright (C) 1994, C++ version by Alejandro Aguilar Sierra
|
||||||
|
*
|
||||||
|
* In accordance with the above, I want to credit Steve Wilhite who wrote
|
||||||
|
* the code which this is heavily inspired by...
|
||||||
|
*
|
||||||
|
* GIF and 'Graphics Interchange Format' are trademarks (tm) of
|
||||||
|
* Compuserve, Incorporated, an H&R Block Company.
|
||||||
|
*
|
||||||
|
* Release Notes: This file contains a decoder routine for GIF images
|
||||||
|
* which is similar, structurally, to the original routine by Steve Wilhite.
|
||||||
|
* It is, however, somewhat noticably faster in most cases.
|
||||||
|
*
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__ximaGIF_h)
|
||||||
|
#define __ximaGIF_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_GIF
|
||||||
|
|
||||||
|
typedef int16_t code_int;
|
||||||
|
|
||||||
|
/* Various error codes used by decoder */
|
||||||
|
#define OUT_OF_MEMORY -10
|
||||||
|
#define BAD_CODE_SIZE -20
|
||||||
|
#define READ_ERROR -1
|
||||||
|
#define WRITE_ERROR -2
|
||||||
|
#define OPEN_ERROR -3
|
||||||
|
#define CREATE_ERROR -4
|
||||||
|
#define BAD_LINE_WIDTH -5
|
||||||
|
#define MAX_CODES 4095
|
||||||
|
#define GIFBUFTAM 16383
|
||||||
|
#define TRANSPARENCY_CODE 0xF9
|
||||||
|
|
||||||
|
//LZW GIF Image compression
|
||||||
|
#define MAXBITSCODES 12
|
||||||
|
#define HSIZE 5003 /* 80% occupancy */
|
||||||
|
#define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
|
||||||
|
#define HashTabOf(i) htab[i]
|
||||||
|
#define CodeTabOf(i) codetab[i]
|
||||||
|
|
||||||
|
|
||||||
|
class CImageIterator;
|
||||||
|
class DLL_EXP CxImageGIF: public CxImage
|
||||||
|
{
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct tag_gifgce{
|
||||||
|
uint8_t flags; /*res:3|dispmeth:3|userinputflag:1|transpcolflag:1*/
|
||||||
|
uint16_t delaytime;
|
||||||
|
uint8_t transpcolindex;
|
||||||
|
} struct_gifgce;
|
||||||
|
|
||||||
|
typedef struct tag_dscgif{ /* Logic Screen Descriptor */
|
||||||
|
char header[6]; /* Firma and version */
|
||||||
|
uint16_t scrwidth;
|
||||||
|
uint16_t scrheight;
|
||||||
|
char pflds;
|
||||||
|
char bcindx;
|
||||||
|
char pxasrat;
|
||||||
|
} struct_dscgif;
|
||||||
|
|
||||||
|
typedef struct tag_image{ /* Image Descriptor */
|
||||||
|
uint16_t l;
|
||||||
|
uint16_t t;
|
||||||
|
uint16_t w;
|
||||||
|
uint16_t h;
|
||||||
|
uint8_t pf;
|
||||||
|
} struct_image;
|
||||||
|
|
||||||
|
typedef struct tag_TabCol{ /* Tabla de colores */
|
||||||
|
int16_t colres; /* color resolution */
|
||||||
|
int16_t sogct; /* size of global color table */
|
||||||
|
rgb_color paleta[256]; /* paleta */
|
||||||
|
} struct_TabCol;
|
||||||
|
|
||||||
|
typedef struct tag_RLE{
|
||||||
|
int32_t rl_pixel;
|
||||||
|
int32_t rl_basecode;
|
||||||
|
int32_t rl_count;
|
||||||
|
int32_t rl_table_pixel;
|
||||||
|
int32_t rl_table_max;
|
||||||
|
int32_t just_cleared;
|
||||||
|
int32_t out_bits;
|
||||||
|
int32_t out_bits_init;
|
||||||
|
int32_t out_count;
|
||||||
|
int32_t out_bump;
|
||||||
|
int32_t out_bump_init;
|
||||||
|
int32_t out_clear;
|
||||||
|
int32_t out_clear_init;
|
||||||
|
int32_t max_ocodes;
|
||||||
|
int32_t code_clear;
|
||||||
|
int32_t code_eof;
|
||||||
|
uint32_t obuf;
|
||||||
|
int32_t obits;
|
||||||
|
uint8_t oblock[256];
|
||||||
|
int32_t oblen;
|
||||||
|
} struct_RLE;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImageGIF();
|
||||||
|
~CxImageGIF();
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_GIF);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_GIF);}
|
||||||
|
|
||||||
|
bool Decode(CxFile * fp);
|
||||||
|
bool Decode(FILE *fp) { CxIOFile file(fp); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * fp);
|
||||||
|
bool Encode(CxFile * fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap = false, bool bLocalDispMeth = false);
|
||||||
|
bool Encode(FILE *fp) { CxIOFile file(fp); return Encode(&file); }
|
||||||
|
bool Encode(FILE *fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap = false)
|
||||||
|
{ CxIOFile file(fp); return Encode(&file, pImages, pagecount, bLocalColorMap); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
void SetLoops(int32_t loops);
|
||||||
|
int32_t GetLoops();
|
||||||
|
void SetComment(const char* sz_comment_in);
|
||||||
|
void GetComment(char* sz_comment_out);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool DecodeExtension(CxFile *fp);
|
||||||
|
void EncodeHeader(CxFile *fp);
|
||||||
|
void EncodeLoopExtension(CxFile *fp);
|
||||||
|
void EncodeExtension(CxFile *fp);
|
||||||
|
void EncodeBody(CxFile *fp, bool bLocalColorMap = false);
|
||||||
|
void EncodeComment(CxFile *fp);
|
||||||
|
bool EncodeRGB(CxFile *fp);
|
||||||
|
void GifMix(CxImage & imgsrc2, struct_image & imgdesc);
|
||||||
|
|
||||||
|
struct_gifgce gifgce;
|
||||||
|
|
||||||
|
int32_t curx, cury;
|
||||||
|
int32_t CountDown;
|
||||||
|
uint32_t cur_accum;
|
||||||
|
int32_t cur_bits;
|
||||||
|
int32_t interlaced, iypos, istep, iheight, ipass;
|
||||||
|
int32_t ibf;
|
||||||
|
int32_t ibfmax;
|
||||||
|
uint8_t * buf;
|
||||||
|
// Implementation
|
||||||
|
int32_t GifNextPixel ();
|
||||||
|
void Putword (int32_t w, CxFile* fp );
|
||||||
|
void compressNONE (int32_t init_bits, CxFile* outfile);
|
||||||
|
void compressLZW (int32_t init_bits, CxFile* outfile);
|
||||||
|
void output (code_int code );
|
||||||
|
void cl_hash (int32_t hsize);
|
||||||
|
void char_out (int32_t c);
|
||||||
|
void flush_char ();
|
||||||
|
int16_t init_exp(int16_t size);
|
||||||
|
int16_t get_next_code(CxFile*);
|
||||||
|
int16_t decoder(CxFile*, CImageIterator* iter, int16_t linewidth, int32_t &bad_code_count);
|
||||||
|
int32_t get_byte(CxFile*);
|
||||||
|
int32_t out_line(CImageIterator* iter, uint8_t *pixels, int32_t linelen);
|
||||||
|
int32_t get_num_frames(CxFile *f,struct_TabCol* TabColSrc,struct_dscgif* dscgif);
|
||||||
|
int32_t seek_next_image(CxFile* fp, int32_t position);
|
||||||
|
|
||||||
|
int16_t curr_size; /* The current code size */
|
||||||
|
int16_t clear; /* Value for a clear code */
|
||||||
|
int16_t ending; /* Value for a ending code */
|
||||||
|
int16_t newcodes; /* First available code */
|
||||||
|
int16_t top_slot; /* Highest code for current size */
|
||||||
|
int16_t slot; /* Last read code */
|
||||||
|
|
||||||
|
/* The following static variables are used
|
||||||
|
* for seperating out codes */
|
||||||
|
int16_t navail_bytes; /* # bytes left in block */
|
||||||
|
int16_t nbits_left; /* # bits left in current uint8_t */
|
||||||
|
uint8_t b1; /* Current uint8_t */
|
||||||
|
uint8_t * byte_buff; /* Current block */
|
||||||
|
uint8_t *pbytes; /* Pointer to next uint8_t in block */
|
||||||
|
/* The reason we have these seperated like this instead of using
|
||||||
|
* a structure like the original Wilhite code did, is because this
|
||||||
|
* stuff generally produces significantly faster code when compiled...
|
||||||
|
* This code is full of similar speedups... (For a good book on writing
|
||||||
|
* C for speed or for space optomisation, see Efficient C by Tom Plum,
|
||||||
|
* published by Plum-Hall Associates...)
|
||||||
|
*/
|
||||||
|
uint8_t * stack; /* Stack for storing pixels */
|
||||||
|
uint8_t * suffix; /* Suffix table */
|
||||||
|
uint16_t * prefix; /* Prefix linked list */
|
||||||
|
|
||||||
|
//LZW GIF Image compression routines
|
||||||
|
int32_t * htab;
|
||||||
|
uint16_t * codetab;
|
||||||
|
int32_t n_bits; /* number of bits/code */
|
||||||
|
code_int maxcode; /* maximum code, given n_bits */
|
||||||
|
code_int free_ent; /* first unused entry */
|
||||||
|
int32_t clear_flg;
|
||||||
|
int32_t g_init_bits;
|
||||||
|
CxFile* g_outfile;
|
||||||
|
int32_t ClearCode;
|
||||||
|
int32_t EOFCode;
|
||||||
|
|
||||||
|
int32_t a_count;
|
||||||
|
char * accum;
|
||||||
|
|
||||||
|
char * m_comment;
|
||||||
|
int32_t m_loops;
|
||||||
|
|
||||||
|
//RLE compression routines
|
||||||
|
void compressRLE( int32_t init_bits, CxFile* outfile);
|
||||||
|
void rle_clear(struct_RLE* rle);
|
||||||
|
void rle_flush(struct_RLE* rle);
|
||||||
|
void rle_flush_withtable(int32_t count, struct_RLE* rle);
|
||||||
|
void rle_flush_clearorrep(int32_t count, struct_RLE* rle);
|
||||||
|
void rle_flush_fromclear(int32_t count,struct_RLE* rle);
|
||||||
|
void rle_output_plain(int32_t c,struct_RLE* rle);
|
||||||
|
void rle_reset_out_clear(struct_RLE* rle);
|
||||||
|
uint32_t rle_compute_triangle_count(uint32_t count, uint32_t nrepcodes);
|
||||||
|
uint32_t rle_isqrt(uint32_t x);
|
||||||
|
void rle_write_block(struct_RLE* rle);
|
||||||
|
void rle_block_out(uint8_t c, struct_RLE* rle);
|
||||||
|
void rle_block_flush(struct_RLE* rle);
|
||||||
|
void rle_output(int32_t val, struct_RLE* rle);
|
||||||
|
void rle_output_flush(struct_RLE* rle);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
627
Raw2Bmp_MFC/include/ximahist.cpp
Normal file
627
Raw2Bmp_MFC/include/ximahist.cpp
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
// xImaHist.cpp : histogram functions
|
||||||
|
/* 28/01/2004 v1.00 - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_DSP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int32_t CxImage::Histogram(int32_t* red, int32_t* green, int32_t* blue, int32_t* gray, int32_t colorspace)
|
||||||
|
{
|
||||||
|
if (!pDib) return 0;
|
||||||
|
RGBQUAD color;
|
||||||
|
|
||||||
|
if (red) memset(red,0,256*sizeof(int32_t));
|
||||||
|
if (green) memset(green,0,256*sizeof(int32_t));
|
||||||
|
if (blue) memset(blue,0,256*sizeof(int32_t));
|
||||||
|
if (gray) memset(gray,0,256*sizeof(int32_t));
|
||||||
|
|
||||||
|
int32_t xmin,xmax,ymin,ymax;
|
||||||
|
if (pSelection){
|
||||||
|
xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
|
||||||
|
ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
|
||||||
|
} else {
|
||||||
|
xmin = ymin = 0;
|
||||||
|
xmax = head.biWidth; ymax=head.biHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t y=ymin; y<ymax; y++){
|
||||||
|
for(int32_t x=xmin; x<xmax; x++){
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
if (BlindSelectionIsInside(x,y))
|
||||||
|
#endif //CXIMAGE_SUPPORT_SELECTION
|
||||||
|
{
|
||||||
|
switch (colorspace){
|
||||||
|
case 1:
|
||||||
|
color = HSLtoRGB(BlindGetPixelColor(x,y));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = YUVtoRGB(BlindGetPixelColor(x,y));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
color = YIQtoRGB(BlindGetPixelColor(x,y));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
color = XYZtoRGB(BlindGetPixelColor(x,y));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = BlindGetPixelColor(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (red) red[color.rgbRed]++;
|
||||||
|
if (green) green[color.rgbGreen]++;
|
||||||
|
if (blue) blue[color.rgbBlue]++;
|
||||||
|
if (gray) gray[(uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t n=0;
|
||||||
|
for (int32_t i=0; i<256; i++){
|
||||||
|
if (red && red[i]>n) n=red[i];
|
||||||
|
if (green && green[i]>n) n=green[i];
|
||||||
|
if (blue && blue[i]>n) n=blue[i];
|
||||||
|
if (gray && gray[i]>n) n=gray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* HistogramStretch
|
||||||
|
* \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
|
||||||
|
* \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%);
|
||||||
|
* \return true if everything is ok
|
||||||
|
* \author [dave] and [nipper]; changes [DP]
|
||||||
|
*/
|
||||||
|
bool CxImage::HistogramStretch(int32_t method, double threshold)
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
|
||||||
|
double dbScaler = 50.0/head.biHeight;
|
||||||
|
int32_t x,y;
|
||||||
|
|
||||||
|
if ((head.biBitCount==8) && IsGrayScale()){
|
||||||
|
|
||||||
|
double p[256];
|
||||||
|
memset(p, 0, 256*sizeof(double));
|
||||||
|
for (y=0; y<head.biHeight; y++)
|
||||||
|
{
|
||||||
|
info.nProgress = (int32_t)(y*dbScaler);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for (x=0; x<head.biWidth; x++) {
|
||||||
|
p[BlindGetPixelIndex(x, y)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double maxh = 0;
|
||||||
|
for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
|
||||||
|
threshold *= maxh;
|
||||||
|
int32_t minc = 0;
|
||||||
|
while (minc<255 && p[minc]<=threshold) minc++;
|
||||||
|
int32_t maxc = 255;
|
||||||
|
while (maxc>0 && p[maxc]<=threshold) maxc--;
|
||||||
|
|
||||||
|
if (minc == 0 && maxc == 255) return true;
|
||||||
|
if (minc >= maxc) return true;
|
||||||
|
|
||||||
|
// calculate LUT
|
||||||
|
uint8_t lut[256];
|
||||||
|
for (x = 0; x <256; x++){
|
||||||
|
lut[x] = (uint8_t)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y=0; y<head.biHeight; y++) {
|
||||||
|
if (info.nEscape) break;
|
||||||
|
info.nProgress = (int32_t)(50.0+y*dbScaler);
|
||||||
|
for (x=0; x<head.biWidth; x++)
|
||||||
|
{
|
||||||
|
BlindSetPixelIndex(x, y, lut[BlindGetPixelIndex(x, y)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(method){
|
||||||
|
case 1:
|
||||||
|
{ // <nipper>
|
||||||
|
double p[256];
|
||||||
|
memset(p, 0, 256*sizeof(double));
|
||||||
|
for (y=0; y<head.biHeight; y++)
|
||||||
|
{
|
||||||
|
info.nProgress = (int32_t)(y*dbScaler);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for (x=0; x<head.biWidth; x++) {
|
||||||
|
RGBQUAD color = BlindGetPixelColor(x, y);
|
||||||
|
p[color.rgbRed]++;
|
||||||
|
p[color.rgbBlue]++;
|
||||||
|
p[color.rgbGreen]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double maxh = 0;
|
||||||
|
for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
|
||||||
|
threshold *= maxh;
|
||||||
|
int32_t minc = 0;
|
||||||
|
while (minc<255 && p[minc]<=threshold) minc++;
|
||||||
|
int32_t maxc = 255;
|
||||||
|
while (maxc>0 && p[maxc]<=threshold) maxc--;
|
||||||
|
|
||||||
|
if (minc == 0 && maxc == 255) return true;
|
||||||
|
if (minc >= maxc) return true;
|
||||||
|
|
||||||
|
// calculate LUT
|
||||||
|
uint8_t lut[256];
|
||||||
|
for (x = 0; x <256; x++){
|
||||||
|
lut[x] = (uint8_t)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize image
|
||||||
|
for (y=0; y<head.biHeight; y++) {
|
||||||
|
if (info.nEscape) break;
|
||||||
|
info.nProgress = (int32_t)(50.0+y*dbScaler);
|
||||||
|
|
||||||
|
for (x=0; x<head.biWidth; x++)
|
||||||
|
{
|
||||||
|
RGBQUAD color = BlindGetPixelColor(x, y);
|
||||||
|
|
||||||
|
color.rgbRed = lut[color.rgbRed];
|
||||||
|
color.rgbBlue = lut[color.rgbBlue];
|
||||||
|
color.rgbGreen = lut[color.rgbGreen];
|
||||||
|
|
||||||
|
BlindSetPixelColor(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{ // <nipper>
|
||||||
|
double pR[256];
|
||||||
|
memset(pR, 0, 256*sizeof(double));
|
||||||
|
double pG[256];
|
||||||
|
memset(pG, 0, 256*sizeof(double));
|
||||||
|
double pB[256];
|
||||||
|
memset(pB, 0, 256*sizeof(double));
|
||||||
|
for (y=0; y<head.biHeight; y++)
|
||||||
|
{
|
||||||
|
info.nProgress = (int32_t)(y*dbScaler);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for (int32_t x=0; x<head.biWidth; x++) {
|
||||||
|
RGBQUAD color = BlindGetPixelColor(x, y);
|
||||||
|
pR[color.rgbRed]++;
|
||||||
|
pB[color.rgbBlue]++;
|
||||||
|
pG[color.rgbGreen]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double maxh = 0;
|
||||||
|
for (y=0; y<255; y++) if (maxh < pR[y]) maxh = pR[y];
|
||||||
|
double threshold2 = threshold*maxh;
|
||||||
|
int32_t minR = 0;
|
||||||
|
while (minR<255 && pR[minR]<=threshold2) minR++;
|
||||||
|
int32_t maxR = 255;
|
||||||
|
while (maxR>0 && pR[maxR]<=threshold2) maxR--;
|
||||||
|
|
||||||
|
maxh = 0;
|
||||||
|
for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y];
|
||||||
|
threshold2 = threshold*maxh;
|
||||||
|
int32_t minG = 0;
|
||||||
|
while (minG<255 && pG[minG]<=threshold2) minG++;
|
||||||
|
int32_t maxG = 255;
|
||||||
|
while (maxG>0 && pG[maxG]<=threshold2) maxG--;
|
||||||
|
|
||||||
|
maxh = 0;
|
||||||
|
for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y];
|
||||||
|
threshold2 = threshold*maxh;
|
||||||
|
int32_t minB = 0;
|
||||||
|
while (minB<255 && pB[minB]<=threshold2) minB++;
|
||||||
|
int32_t maxB = 255;
|
||||||
|
while (maxB>0 && pB[maxB]<=threshold2) maxB--;
|
||||||
|
|
||||||
|
if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// calculate LUT
|
||||||
|
uint8_t lutR[256];
|
||||||
|
uint8_t range = maxR - minR;
|
||||||
|
if (range != 0) {
|
||||||
|
for (x = 0; x <256; x++){
|
||||||
|
lutR[x] = (uint8_t)max(0,min(255,(255 * (x - minR) / range)));
|
||||||
|
}
|
||||||
|
} else lutR[minR] = minR;
|
||||||
|
|
||||||
|
uint8_t lutG[256];
|
||||||
|
range = maxG - minG;
|
||||||
|
if (range != 0) {
|
||||||
|
for (x = 0; x <256; x++){
|
||||||
|
lutG[x] = (uint8_t)max(0,min(255,(255 * (x - minG) / range)));
|
||||||
|
}
|
||||||
|
} else lutG[minG] = minG;
|
||||||
|
|
||||||
|
uint8_t lutB[256];
|
||||||
|
range = maxB - minB;
|
||||||
|
if (range != 0) {
|
||||||
|
for (x = 0; x <256; x++){
|
||||||
|
lutB[x] = (uint8_t)max(0,min(255,(255 * (x - minB) / range)));
|
||||||
|
}
|
||||||
|
} else lutB[minB] = minB;
|
||||||
|
|
||||||
|
// normalize image
|
||||||
|
for (y=0; y<head.biHeight; y++)
|
||||||
|
{
|
||||||
|
info.nProgress = (int32_t)(50.0+y*dbScaler);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
|
||||||
|
for (x=0; x<head.biWidth; x++)
|
||||||
|
{
|
||||||
|
RGBQUAD color = BlindGetPixelColor(x, y);
|
||||||
|
|
||||||
|
color.rgbRed = lutR[color.rgbRed];
|
||||||
|
color.rgbBlue = lutB[color.rgbBlue];
|
||||||
|
color.rgbGreen = lutG[color.rgbGreen];
|
||||||
|
|
||||||
|
BlindSetPixelColor(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{ // <dave>
|
||||||
|
double p[256];
|
||||||
|
memset(p, 0, 256*sizeof(double));
|
||||||
|
for (y=0; y<head.biHeight; y++)
|
||||||
|
{
|
||||||
|
info.nProgress = (int32_t)(y*dbScaler);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for (x=0; x<head.biWidth; x++) {
|
||||||
|
RGBQUAD color = BlindGetPixelColor(x, y);
|
||||||
|
p[RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double maxh = 0;
|
||||||
|
for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
|
||||||
|
threshold *= maxh;
|
||||||
|
int32_t minc = 0;
|
||||||
|
while (minc<255 && p[minc]<=threshold) minc++;
|
||||||
|
int32_t maxc = 255;
|
||||||
|
while (maxc>0 && p[maxc]<=threshold) maxc--;
|
||||||
|
|
||||||
|
if (minc == 0 && maxc == 255) return true;
|
||||||
|
if (minc >= maxc) return true;
|
||||||
|
|
||||||
|
// calculate LUT
|
||||||
|
uint8_t lut[256];
|
||||||
|
for (x = 0; x <256; x++){
|
||||||
|
lut[x] = (uint8_t)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(y=0; y<head.biHeight; y++){
|
||||||
|
info.nProgress = (int32_t)(50.0+y*dbScaler);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for(x=0; x<head.biWidth; x++){
|
||||||
|
|
||||||
|
RGBQUAD color = BlindGetPixelColor( x, y );
|
||||||
|
RGBQUAD yuvClr = RGBtoYUV(color);
|
||||||
|
yuvClr.rgbRed = lut[yuvClr.rgbRed];
|
||||||
|
color = YUVtoRGB(yuvClr);
|
||||||
|
BlindSetPixelColor( x, y, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
|
||||||
|
bool CxImage::HistogramEqualize()
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
|
||||||
|
int32_t histogram[256];
|
||||||
|
int32_t map[256];
|
||||||
|
int32_t equalize_map[256];
|
||||||
|
int32_t x, y, i, j;
|
||||||
|
RGBQUAD color;
|
||||||
|
RGBQUAD yuvClr;
|
||||||
|
uint32_t YVal, high, low;
|
||||||
|
|
||||||
|
memset( &histogram, 0, sizeof(int32_t) * 256 );
|
||||||
|
memset( &map, 0, sizeof(int32_t) * 256 );
|
||||||
|
memset( &equalize_map, 0, sizeof(int32_t) * 256 );
|
||||||
|
|
||||||
|
// form histogram
|
||||||
|
for(y=0; y < head.biHeight; y++){
|
||||||
|
info.nProgress = (int32_t)(50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for(x=0; x < head.biWidth; x++){
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
|
||||||
|
histogram[YVal]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// integrate the histogram to get the equalization map.
|
||||||
|
j = 0;
|
||||||
|
for(i=0; i <= 255; i++){
|
||||||
|
j += histogram[i];
|
||||||
|
map[i] = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
// equalize
|
||||||
|
low = map[0];
|
||||||
|
high = map[255];
|
||||||
|
if (low == high) return false;
|
||||||
|
for( i = 0; i <= 255; i++ ){
|
||||||
|
equalize_map[i] = (uint32_t)((((double)( map[i] - low ) ) * 255) / ( high - low ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// stretch the histogram
|
||||||
|
if(head.biClrUsed == 0){ // No Palette
|
||||||
|
for( y = 0; y < head.biHeight; y++ ){
|
||||||
|
info.nProgress = (int32_t)(50+50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for( x = 0; x < head.biWidth; x++ ){
|
||||||
|
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
yuvClr = RGBtoYUV(color);
|
||||||
|
|
||||||
|
yuvClr.rgbRed = (uint8_t)equalize_map[yuvClr.rgbRed];
|
||||||
|
|
||||||
|
color = YUVtoRGB(yuvClr);
|
||||||
|
BlindSetPixelColor( x, y, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Palette
|
||||||
|
for( i = 0; i < (int32_t)head.biClrUsed; i++ ){
|
||||||
|
|
||||||
|
color = GetPaletteColor((uint8_t)i);
|
||||||
|
yuvClr = RGBtoYUV(color);
|
||||||
|
|
||||||
|
yuvClr.rgbRed = (uint8_t)equalize_map[yuvClr.rgbRed];
|
||||||
|
|
||||||
|
color = YUVtoRGB(yuvClr);
|
||||||
|
SetPaletteColor( (uint8_t)i, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
|
||||||
|
bool CxImage::HistogramNormalize()
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
|
||||||
|
int32_t histogram[256];
|
||||||
|
int32_t threshold_intensity, intense;
|
||||||
|
int32_t x, y, i;
|
||||||
|
uint32_t normalize_map[256];
|
||||||
|
uint32_t high, low, YVal;
|
||||||
|
|
||||||
|
RGBQUAD color;
|
||||||
|
RGBQUAD yuvClr;
|
||||||
|
|
||||||
|
memset( &histogram, 0, sizeof( int32_t ) * 256 );
|
||||||
|
memset( &normalize_map, 0, sizeof( uint32_t ) * 256 );
|
||||||
|
|
||||||
|
// form histogram
|
||||||
|
for(y=0; y < head.biHeight; y++){
|
||||||
|
info.nProgress = (int32_t)(50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for(x=0; x < head.biWidth; x++){
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
|
||||||
|
histogram[YVal]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find histogram boundaries by locating the 1 percent levels
|
||||||
|
threshold_intensity = ( head.biWidth * head.biHeight) / 100;
|
||||||
|
|
||||||
|
intense = 0;
|
||||||
|
for( low = 0; low < 255; low++ ){
|
||||||
|
intense += histogram[low];
|
||||||
|
if( intense > threshold_intensity ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
intense = 0;
|
||||||
|
for( high = 255; high != 0; high--){
|
||||||
|
intense += histogram[ high ];
|
||||||
|
if( intense > threshold_intensity ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( low == high ){
|
||||||
|
// Unreasonable contrast; use zero threshold to determine boundaries.
|
||||||
|
threshold_intensity = 0;
|
||||||
|
intense = 0;
|
||||||
|
for( low = 0; low < 255; low++){
|
||||||
|
intense += histogram[low];
|
||||||
|
if( intense > threshold_intensity ) break;
|
||||||
|
}
|
||||||
|
intense = 0;
|
||||||
|
for( high = 255; high != 0; high-- ){
|
||||||
|
intense += histogram [high ];
|
||||||
|
if( intense > threshold_intensity ) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( low == high ) return false; // zero span bound
|
||||||
|
|
||||||
|
// Stretch the histogram to create the normalized image mapping.
|
||||||
|
for(i = 0; i <= 255; i++){
|
||||||
|
if ( i < (int32_t) low ){
|
||||||
|
normalize_map[i] = 0;
|
||||||
|
} else {
|
||||||
|
if(i > (int32_t) high)
|
||||||
|
normalize_map[i] = 255;
|
||||||
|
else
|
||||||
|
normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
if( head.biClrUsed == 0 ){
|
||||||
|
for( y = 0; y < head.biHeight; y++ ){
|
||||||
|
info.nProgress = (int32_t)(50+50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for( x = 0; x < head.biWidth; x++ ){
|
||||||
|
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
yuvClr = RGBtoYUV( color );
|
||||||
|
|
||||||
|
yuvClr.rgbRed = (uint8_t)normalize_map[yuvClr.rgbRed];
|
||||||
|
|
||||||
|
color = YUVtoRGB( yuvClr );
|
||||||
|
BlindSetPixelColor( x, y, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < (int32_t)head.biClrUsed; i++){
|
||||||
|
|
||||||
|
color = GetPaletteColor( (uint8_t)i );
|
||||||
|
yuvClr = RGBtoYUV( color );
|
||||||
|
|
||||||
|
yuvClr.rgbRed = (uint8_t)normalize_map[yuvClr.rgbRed];
|
||||||
|
|
||||||
|
color = YUVtoRGB( yuvClr );
|
||||||
|
SetPaletteColor( (uint8_t)i, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// HistogramLog function by <dave> : dave(at)posortho(dot)com
|
||||||
|
bool CxImage::HistogramLog()
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
|
||||||
|
//q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|);
|
||||||
|
int32_t x, y, i;
|
||||||
|
RGBQUAD color;
|
||||||
|
RGBQUAD yuvClr;
|
||||||
|
|
||||||
|
uint32_t YVal, high = 1;
|
||||||
|
|
||||||
|
// Find Highest Luminance Value in the Image
|
||||||
|
if( head.biClrUsed == 0 ){ // No Palette
|
||||||
|
for(y=0; y < head.biHeight; y++){
|
||||||
|
info.nProgress = (int32_t)(50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for(x=0; x < head.biWidth; x++){
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
|
||||||
|
if (YVal > high ) high = YVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Palette
|
||||||
|
for(i = 0; i < (int32_t)head.biClrUsed; i++){
|
||||||
|
color = GetPaletteColor((uint8_t)i);
|
||||||
|
YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
|
||||||
|
if (YVal > high ) high = YVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logarithm Operator
|
||||||
|
double k = 255.0 / ::log( 1.0 + (double)high );
|
||||||
|
if( head.biClrUsed == 0 ){
|
||||||
|
for( y = 0; y < head.biHeight; y++ ){
|
||||||
|
info.nProgress = (int32_t)(50+50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for( x = 0; x < head.biWidth; x++ ){
|
||||||
|
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
yuvClr = RGBtoYUV( color );
|
||||||
|
|
||||||
|
yuvClr.rgbRed = (uint8_t)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
|
||||||
|
|
||||||
|
color = YUVtoRGB( yuvClr );
|
||||||
|
BlindSetPixelColor( x, y, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < (int32_t)head.biClrUsed; i++){
|
||||||
|
|
||||||
|
color = GetPaletteColor( (uint8_t)i );
|
||||||
|
yuvClr = RGBtoYUV( color );
|
||||||
|
|
||||||
|
yuvClr.rgbRed = (uint8_t)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
|
||||||
|
|
||||||
|
color = YUVtoRGB( yuvClr );
|
||||||
|
SetPaletteColor( (uint8_t)i, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// HistogramRoot function by <dave> : dave(at)posortho(dot)com
|
||||||
|
bool CxImage::HistogramRoot()
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
//q(i,j) = sqrt(|p(i,j)|);
|
||||||
|
|
||||||
|
int32_t x, y, i;
|
||||||
|
RGBQUAD color;
|
||||||
|
RGBQUAD yuvClr;
|
||||||
|
double dtmp;
|
||||||
|
uint32_t YVal, high = 1;
|
||||||
|
|
||||||
|
// Find Highest Luminance Value in the Image
|
||||||
|
if( head.biClrUsed == 0 ){ // No Palette
|
||||||
|
for(y=0; y < head.biHeight; y++){
|
||||||
|
info.nProgress = (int32_t)(50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for(x=0; x < head.biWidth; x++){
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
|
||||||
|
if (YVal > high ) high = YVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Palette
|
||||||
|
for(i = 0; i < (int32_t)head.biClrUsed; i++){
|
||||||
|
color = GetPaletteColor((uint8_t)i);
|
||||||
|
YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
|
||||||
|
if (YVal > high ) high = YVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root Operator
|
||||||
|
double k = 256.0 / ::sqrt( 1.0 + (double)high );
|
||||||
|
if( head.biClrUsed == 0 ){
|
||||||
|
for( y = 0; y < head.biHeight; y++ ){
|
||||||
|
info.nProgress = (int32_t)(50+50*y/head.biHeight);
|
||||||
|
if (info.nEscape) break;
|
||||||
|
for( x = 0; x < head.biWidth; x++ ){
|
||||||
|
|
||||||
|
color = BlindGetPixelColor( x, y );
|
||||||
|
yuvClr = RGBtoYUV( color );
|
||||||
|
|
||||||
|
dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
|
||||||
|
if ( dtmp > 255.0 ) dtmp = 255.0;
|
||||||
|
if ( dtmp < 0 ) dtmp = 0;
|
||||||
|
yuvClr.rgbRed = (uint8_t)dtmp;
|
||||||
|
|
||||||
|
color = YUVtoRGB( yuvClr );
|
||||||
|
BlindSetPixelColor( x, y, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < (int32_t)head.biClrUsed; i++){
|
||||||
|
|
||||||
|
color = GetPaletteColor( (uint8_t)i );
|
||||||
|
yuvClr = RGBtoYUV( color );
|
||||||
|
|
||||||
|
dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
|
||||||
|
if ( dtmp > 255.0 ) dtmp = 255.0;
|
||||||
|
if ( dtmp < 0 ) dtmp = 0;
|
||||||
|
yuvClr.rgbRed = (uint8_t)dtmp;
|
||||||
|
|
||||||
|
color = YUVtoRGB( yuvClr );
|
||||||
|
SetPaletteColor( (uint8_t)i, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif
|
||||||
470
Raw2Bmp_MFC/include/ximaico.cpp
Normal file
470
Raw2Bmp_MFC/include/ximaico.cpp
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaico.cpp
|
||||||
|
* Purpose: Platform Independent ICON Image Class Loader and Writer (MS version)
|
||||||
|
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximaico.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageICO::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile==NULL) return false;
|
||||||
|
|
||||||
|
uint32_t off = hFile->Tell(); //<yuandi>
|
||||||
|
int32_t page=info.nFrame; //internal icon structure indexes
|
||||||
|
|
||||||
|
// read the first part of the header
|
||||||
|
ICONHEADER icon_header;
|
||||||
|
hFile->Read(&icon_header,sizeof(ICONHEADER),1);
|
||||||
|
|
||||||
|
icon_header.idType = m_ntohs(icon_header.idType);
|
||||||
|
icon_header.idCount = m_ntohs(icon_header.idCount);
|
||||||
|
|
||||||
|
// check if it's an icon or a cursor
|
||||||
|
if ((icon_header.idReserved == 0) && ((icon_header.idType == 1)||(icon_header.idType == 2))) {
|
||||||
|
|
||||||
|
info.nNumFrames = icon_header.idCount;
|
||||||
|
|
||||||
|
// load the icon descriptions
|
||||||
|
ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header.idCount * sizeof(ICONDIRENTRY));
|
||||||
|
int32_t c;
|
||||||
|
for (c = 0; c < icon_header.idCount; c++) {
|
||||||
|
hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);
|
||||||
|
|
||||||
|
icon_list[c].wPlanes = m_ntohs(icon_list[c].wPlanes);
|
||||||
|
icon_list[c].wBitCount = m_ntohs(icon_list[c].wBitCount);
|
||||||
|
icon_list[c].dwBytesInRes = m_ntohl(icon_list[c].dwBytesInRes);
|
||||||
|
icon_list[c].dwImageOffset = m_ntohl(icon_list[c].dwImageOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((page>=0)&&(page<icon_header.idCount)){
|
||||||
|
|
||||||
|
if (info.nEscape == -1) {
|
||||||
|
// Return output dimensions only
|
||||||
|
head.biWidth = icon_list[page].bWidth;
|
||||||
|
head.biHeight = icon_list[page].bHeight;
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
if (head.biWidth==0 && head.biHeight==0)
|
||||||
|
{ // Vista icon support
|
||||||
|
hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
|
||||||
|
CxImage png;
|
||||||
|
png.SetEscape(-1);
|
||||||
|
if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
|
||||||
|
Transfer(png);
|
||||||
|
info.nNumFrames = icon_header.idCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //CXIMAGE_SUPPORT_PNG
|
||||||
|
free(icon_list);
|
||||||
|
info.dwType = CXIMAGE_FORMAT_ICO;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the bit count for the colors in the icon <CoreyRLucier>
|
||||||
|
BITMAPINFOHEADER bih;
|
||||||
|
hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
|
||||||
|
|
||||||
|
if (icon_list[page].bWidth==0 && icon_list[page].bHeight==0)
|
||||||
|
{ // Vista icon support
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
CxImage png;
|
||||||
|
if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
|
||||||
|
Transfer(png);
|
||||||
|
info.nNumFrames = icon_header.idCount;
|
||||||
|
}
|
||||||
|
SetType(CXIMAGE_FORMAT_ICO);
|
||||||
|
#endif //CXIMAGE_SUPPORT_PNG
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // standard icon
|
||||||
|
hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);
|
||||||
|
|
||||||
|
bihtoh(&bih);
|
||||||
|
|
||||||
|
c = bih.biBitCount;
|
||||||
|
|
||||||
|
// allocate memory for one icon
|
||||||
|
Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO); //image creation
|
||||||
|
|
||||||
|
// read the palette
|
||||||
|
RGBQUAD pal[256];
|
||||||
|
if (bih.biClrUsed)
|
||||||
|
hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
|
||||||
|
else
|
||||||
|
hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
|
||||||
|
|
||||||
|
SetPalette(pal,head.biClrUsed); //palette assign
|
||||||
|
|
||||||
|
//read the icon
|
||||||
|
if (c<=24){
|
||||||
|
hFile->Read(info.pImage, head.biSizeImage, 1);
|
||||||
|
} else { // 32 bit icon
|
||||||
|
uint8_t* buf=(uint8_t*)malloc(4*head.biHeight*head.biWidth);
|
||||||
|
uint8_t* src = buf;
|
||||||
|
hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (!AlphaIsValid()) AlphaCreate();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
for (int32_t y = 0; y < head.biHeight; y++) {
|
||||||
|
uint8_t* dst = GetBits(y);
|
||||||
|
for(int32_t x=0;x<head.biWidth;x++){
|
||||||
|
*dst++=src[0];
|
||||||
|
*dst++=src[1];
|
||||||
|
*dst++=src[2];
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
AlphaSet(x,y,src[3]);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
src+=4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
// apply the AND and XOR masks
|
||||||
|
int32_t maskwdt = ((head.biWidth+31) / 32) * 4; //line width of AND mask (always 1 Bpp)
|
||||||
|
int32_t masksize = head.biHeight * maskwdt; //size of mask
|
||||||
|
uint8_t *mask = (uint8_t *)malloc(masksize);
|
||||||
|
if (hFile->Read(mask, masksize, 1)){
|
||||||
|
|
||||||
|
bool bGoodMask=false;
|
||||||
|
for (int32_t im=0;im<masksize;im++){
|
||||||
|
if (mask[im]!=255){
|
||||||
|
bGoodMask=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bGoodMask){
|
||||||
|
int32_t x,y;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
bool bNeedAlpha = false;
|
||||||
|
if (!AlphaIsValid()){
|
||||||
|
AlphaCreate();
|
||||||
|
} else {
|
||||||
|
bNeedAlpha=true; //32bit icon
|
||||||
|
}
|
||||||
|
for (y = 0; y < head.biHeight; y++) {
|
||||||
|
for (x = 0; x < head.biWidth; x++) {
|
||||||
|
if (((mask[y*maskwdt+(x>>3)]>>(7-x%8))&0x01)){
|
||||||
|
AlphaSet(x,y,0);
|
||||||
|
bNeedAlpha=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bNeedAlpha) AlphaDelete();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
//check if there is only one transparent color
|
||||||
|
RGBQUAD cc,ct;
|
||||||
|
int32_t nTransColors=0;
|
||||||
|
int32_t nTransIndex=0;
|
||||||
|
for (y = 0; y < head.biHeight; y++){
|
||||||
|
for (x = 0; x < head.biWidth; x++){
|
||||||
|
if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
|
||||||
|
cc = GetPixelColor(x,y,false);
|
||||||
|
if (nTransColors==0){
|
||||||
|
nTransIndex = GetPixelIndex(x,y);
|
||||||
|
nTransColors++;
|
||||||
|
ct = cc;
|
||||||
|
} else {
|
||||||
|
if (memcmp(&cc, &ct, sizeof(RGBQUAD)) != 0){
|
||||||
|
nTransColors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nTransColors==1 && c<=8){
|
||||||
|
SetTransColor(ct);
|
||||||
|
SetTransIndex(nTransIndex);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
AlphaDelete(); //because we have a unique transparent color in the image
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
|
||||||
|
// <vho> - Transparency support w/o Alpha support
|
||||||
|
if (c <= 8){ // only for icons with less than 256 colors (XP icons need alpha).
|
||||||
|
|
||||||
|
// find a color index, which is not used in the image
|
||||||
|
// it is almost sure to find one, bcs. nobody uses all possible colors for an icon
|
||||||
|
|
||||||
|
uint8_t colorsUsed[256];
|
||||||
|
memset(colorsUsed, 0, sizeof(colorsUsed));
|
||||||
|
|
||||||
|
for (y = 0; y < head.biHeight; y++){
|
||||||
|
for (x = 0; x < head.biWidth; x++){
|
||||||
|
colorsUsed[BlindGetPixelIndex(x,y)] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t iTransIdx = -1;
|
||||||
|
for (x = (int32_t)(head.biClrUsed-1); x>=0 ; x--){
|
||||||
|
if (colorsUsed[x] == 0){
|
||||||
|
iTransIdx = x; // this one is not in use. we may use it as transparent color
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go thru image and set unused color as transparent index if needed
|
||||||
|
if (iTransIdx >= 0){
|
||||||
|
bool bNeedTrans = false;
|
||||||
|
for (y = 0; y < head.biHeight; y++){
|
||||||
|
for (x = 0; x < head.biWidth; x++){
|
||||||
|
// AND mask (Each Byte represents 8 Pixels)
|
||||||
|
if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
|
||||||
|
// AND mask is set (!=0). This is a transparent part
|
||||||
|
SetPixelIndex(x, y, (uint8_t)iTransIdx);
|
||||||
|
bNeedTrans = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set transparent index if needed
|
||||||
|
if (bNeedTrans) SetTransIndex(iTransIdx);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
AlphaDelete(); //because we have a transparent color in the palette
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetTransIndex(0); //empty mask, set black as transparent color
|
||||||
|
Negative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(mask);
|
||||||
|
}
|
||||||
|
free(icon_list);
|
||||||
|
// icon has been loaded successfully!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
free(icon_list);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Thanks to <Alas>
|
||||||
|
bool CxImageICO::Encode(CxFile * hFile, CxImage ** pImages, int32_t nPageCount)
|
||||||
|
{
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (hFile==NULL) cx_throw("invalid file pointer");
|
||||||
|
if (pImages==NULL || nPageCount<=0) cx_throw("multipage ICO, no images!");
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
for (i=0; i<nPageCount; i++){
|
||||||
|
if (pImages[i]==NULL)
|
||||||
|
cx_throw("Bad image pointer");
|
||||||
|
if (!(pImages[i]->IsValid()))
|
||||||
|
cx_throw("Empty image");
|
||||||
|
}
|
||||||
|
|
||||||
|
CxImageICO ghost;
|
||||||
|
for (i=0; i<nPageCount; i++){ //write headers
|
||||||
|
ghost.Ghost(pImages[i]);
|
||||||
|
ghost.info.nNumFrames = nPageCount;
|
||||||
|
if (i==0) {
|
||||||
|
if (!ghost.Encode(hFile,false,nPageCount))
|
||||||
|
cx_throw("Error writing ICO file header");
|
||||||
|
}
|
||||||
|
if (!ghost.Encode(hFile,true,nPageCount))
|
||||||
|
cx_throw("Error saving ICO image header");
|
||||||
|
}
|
||||||
|
for (i=0; i<nPageCount; i++){ //write bodies
|
||||||
|
ghost.Ghost(pImages[i]);
|
||||||
|
ghost.info.nNumFrames = nPageCount;
|
||||||
|
if (!ghost.Encode(hFile,true,i))
|
||||||
|
cx_throw("Error saving ICO body");
|
||||||
|
}
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageICO::Encode(CxFile * hFile, bool bAppend, int32_t nPageCount)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PNG == 0
|
||||||
|
//check format limits
|
||||||
|
if ((head.biWidth>255)||(head.biHeight>255)){
|
||||||
|
strcpy(info.szLastError,"Can't save this image as icon");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//prepare the palette struct
|
||||||
|
RGBQUAD* pal=GetPalette();
|
||||||
|
if (head.biBitCount<=8 && pal==NULL) return false;
|
||||||
|
|
||||||
|
int32_t maskwdt=((head.biWidth+31)/32)*4; //mask line width
|
||||||
|
int32_t masksize=head.biHeight * maskwdt; //size of mask
|
||||||
|
int32_t bitcount=head.biBitCount;
|
||||||
|
int32_t imagesize=head.biSizeImage;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (AlphaIsValid() && head.biClrUsed==0){
|
||||||
|
bitcount=32;
|
||||||
|
imagesize=4*head.biHeight*head.biWidth;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//fill the icon headers
|
||||||
|
int32_t nPages = nPageCount;
|
||||||
|
if (nPages<1) nPages = 1;
|
||||||
|
|
||||||
|
ICONHEADER icon_header={0,1,nPages};
|
||||||
|
|
||||||
|
if (!bAppend)
|
||||||
|
m_dwImageOffset = sizeof(ICONHEADER) + nPages * sizeof(ICONDIRENTRY);
|
||||||
|
|
||||||
|
uint32_t dwBytesInRes = sizeof(BITMAPINFOHEADER)+head.biClrUsed*sizeof(RGBQUAD)+imagesize+masksize;
|
||||||
|
|
||||||
|
ICONDIRENTRY icon_list={
|
||||||
|
(uint8_t)head.biWidth,
|
||||||
|
(uint8_t)head.biHeight,
|
||||||
|
(uint8_t)head.biClrUsed,
|
||||||
|
0, 0,
|
||||||
|
(uint16_t)bitcount,
|
||||||
|
dwBytesInRes,
|
||||||
|
m_dwImageOffset
|
||||||
|
};
|
||||||
|
|
||||||
|
BITMAPINFOHEADER bi={
|
||||||
|
sizeof(BITMAPINFOHEADER),
|
||||||
|
head.biWidth,
|
||||||
|
2*head.biHeight,
|
||||||
|
1,
|
||||||
|
(uint16_t)bitcount,
|
||||||
|
0, imagesize,
|
||||||
|
0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PNG // Vista icon support
|
||||||
|
CxImage png(*this);
|
||||||
|
CxMemFile memfile;
|
||||||
|
if (head.biWidth>255 || head.biHeight>255){
|
||||||
|
icon_list.bWidth = icon_list.bHeight = 0;
|
||||||
|
memfile.Open();
|
||||||
|
png.Encode(&memfile,CXIMAGE_FORMAT_PNG);
|
||||||
|
icon_list.dwBytesInRes = dwBytesInRes = memfile.Size();
|
||||||
|
}
|
||||||
|
#endif //CXIMAGE_SUPPORT_PNG
|
||||||
|
|
||||||
|
if (!bAppend){
|
||||||
|
icon_header.idType = m_ntohs(icon_header.idType);
|
||||||
|
icon_header.idCount = m_ntohs(icon_header.idCount);
|
||||||
|
hFile->Write(&icon_header,sizeof(ICONHEADER),1); //write the file header
|
||||||
|
icon_header.idType = m_ntohs(icon_header.idType);
|
||||||
|
icon_header.idCount = m_ntohs(icon_header.idCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((bAppend && nPageCount==info.nNumFrames) || (!bAppend && nPageCount==0)){
|
||||||
|
icon_list.wPlanes = m_ntohs(icon_list.wPlanes);
|
||||||
|
icon_list.wBitCount = m_ntohs(icon_list.wBitCount);
|
||||||
|
icon_list.dwBytesInRes = m_ntohl(icon_list.dwBytesInRes);
|
||||||
|
icon_list.dwImageOffset = m_ntohl(icon_list.dwImageOffset);
|
||||||
|
hFile->Write(&icon_list,sizeof(ICONDIRENTRY),1); //write the image entry
|
||||||
|
icon_list.wPlanes = m_ntohs(icon_list.wPlanes);
|
||||||
|
icon_list.wBitCount = m_ntohs(icon_list.wBitCount);
|
||||||
|
icon_list.dwBytesInRes = m_ntohl(icon_list.dwBytesInRes);
|
||||||
|
icon_list.dwImageOffset = m_ntohl(icon_list.dwImageOffset);
|
||||||
|
|
||||||
|
m_dwImageOffset += dwBytesInRes; //update offset for next header
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bAppend && nPageCount<info.nNumFrames) || (!bAppend && nPageCount==0))
|
||||||
|
{
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
if (icon_list.bWidth==0 && icon_list.bHeight==0) { // Vista icon support
|
||||||
|
hFile->Write(memfile.GetBuffer(false),dwBytesInRes,1);
|
||||||
|
} else
|
||||||
|
#endif //CXIMAGE_SUPPORT_PNG
|
||||||
|
{ // standard icon
|
||||||
|
bihtoh(&bi);
|
||||||
|
hFile->Write(&bi,sizeof(BITMAPINFOHEADER),1); //write the image header
|
||||||
|
bihtoh(&bi);
|
||||||
|
|
||||||
|
bool bTransparent = info.nBkgndIndex >= 0;
|
||||||
|
RGBQUAD ct = GetTransColor();
|
||||||
|
if (pal){
|
||||||
|
if (bTransparent) SetPaletteColor((uint8_t)info.nBkgndIndex,0,0,0,0);
|
||||||
|
hFile->Write(pal,head.biClrUsed*sizeof(RGBQUAD),1); //write palette
|
||||||
|
if (bTransparent) SetPaletteColor((uint8_t)info.nBkgndIndex,ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (AlphaIsValid() && head.biClrUsed==0){
|
||||||
|
uint8_t* buf=(uint8_t*)malloc(imagesize);
|
||||||
|
uint8_t* dst = buf;
|
||||||
|
for (int32_t y = 0; y < head.biHeight; y++) {
|
||||||
|
uint8_t* src = GetBits(y);
|
||||||
|
for(int32_t x=0;x<head.biWidth;x++){
|
||||||
|
*dst++=*src++;
|
||||||
|
*dst++=*src++;
|
||||||
|
*dst++=*src++;
|
||||||
|
*dst++=AlphaGet(x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hFile->Write(buf,imagesize, 1);
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
hFile->Write(info.pImage,imagesize,1); //write image
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
hFile->Write(info.pImage,imagesize,1); //write image
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//save transparency mask
|
||||||
|
uint8_t* mask=(uint8_t*)calloc(masksize,1); //create empty AND/XOR masks
|
||||||
|
if (!mask) return false;
|
||||||
|
|
||||||
|
//prepare the variables to build the mask
|
||||||
|
uint8_t* iDst;
|
||||||
|
int32_t pos,i;
|
||||||
|
RGBQUAD c={0,0,0,0};
|
||||||
|
int32_t* pc = (int32_t*)&c;
|
||||||
|
int32_t* pct= (int32_t*)&ct;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
|
||||||
|
bool bAlphaIsValid = AlphaIsValid();
|
||||||
|
#endif
|
||||||
|
//build the mask
|
||||||
|
for (int32_t y = 0; y < head.biHeight; y++) {
|
||||||
|
for (int32_t x = 0; x < head.biWidth; x++) {
|
||||||
|
i=0;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (bAlphaIsValid && AlphaGet(x,y)==0) i=1;
|
||||||
|
if (bAlphaPaletteIsValid && BlindGetPixelColor(x,y).rgbReserved==0) i=1;
|
||||||
|
#endif
|
||||||
|
c=GetPixelColor(x,y,false);
|
||||||
|
if (bTransparent && *pc==*pct) i=1;
|
||||||
|
iDst = mask + y*maskwdt + (x>>3);
|
||||||
|
pos = 7-x%8;
|
||||||
|
*iDst &= ~(0x01<<pos);
|
||||||
|
*iDst |= ((i & 0x01)<<pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//write AND/XOR masks
|
||||||
|
hFile->Write(mask,masksize,1);
|
||||||
|
free(mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ICO
|
||||||
|
|
||||||
58
Raw2Bmp_MFC/include/ximaico.h
Normal file
58
Raw2Bmp_MFC/include/ximaico.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaico.h
|
||||||
|
* Purpose: ICON Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageICO (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaICO_h)
|
||||||
|
#define __ximaICO_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
|
||||||
|
class CxImageICO: public CxImage
|
||||||
|
{
|
||||||
|
typedef struct tagIconDirectoryEntry {
|
||||||
|
uint8_t bWidth;
|
||||||
|
uint8_t bHeight;
|
||||||
|
uint8_t bColorCount;
|
||||||
|
uint8_t bReserved;
|
||||||
|
uint16_t wPlanes;
|
||||||
|
uint16_t wBitCount;
|
||||||
|
uint32_t dwBytesInRes;
|
||||||
|
uint32_t dwImageOffset;
|
||||||
|
} ICONDIRENTRY;
|
||||||
|
|
||||||
|
typedef struct tagIconDir {
|
||||||
|
uint16_t idReserved;
|
||||||
|
uint16_t idType;
|
||||||
|
uint16_t idCount;
|
||||||
|
} ICONHEADER;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImageICO(): CxImage(CXIMAGE_FORMAT_ICO) {m_dwImageOffset=0;}
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile, bool bAppend=false, int32_t nPageCount=0);
|
||||||
|
bool Encode(CxFile * hFile, CxImage ** pImages, int32_t nPageCount);
|
||||||
|
bool Encode(FILE *hFile, bool bAppend=false, int32_t nPageCount=0)
|
||||||
|
{ CxIOFile file(hFile); return Encode(&file,bAppend,nPageCount); }
|
||||||
|
bool Encode(FILE *hFile, CxImage ** pImages, int32_t nPageCount)
|
||||||
|
{ CxIOFile file(hFile); return Encode(&file, pImages, nPageCount); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
protected:
|
||||||
|
uint32_t m_dwImageOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
958
Raw2Bmp_MFC/include/ximainfo.cpp
Normal file
958
Raw2Bmp_MFC/include/ximainfo.cpp
Normal file
@@ -0,0 +1,958 @@
|
|||||||
|
// ximainfo.cpp : main attributes
|
||||||
|
/* 03/10/2004 v1.00 - Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if defined(_LINUX) || defined(__APPLE__)
|
||||||
|
#define _tcsnicmp(a,b,c) strcasecmp(a,b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return the color used for transparency, and/or for background color
|
||||||
|
*/
|
||||||
|
RGBQUAD CxImage::GetTransColor()
|
||||||
|
{
|
||||||
|
if (head.biBitCount<24 && info.nBkgndIndex>=0) return GetPaletteColor((uint8_t)info.nBkgndIndex);
|
||||||
|
return info.nBkgndColor;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Gets the index used for transparency. Returns -1 for no transparancy.
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetTransIndex() const
|
||||||
|
{
|
||||||
|
return info.nBkgndIndex;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the index used for transparency with 1, 4 and 8 bpp images. Set to -1 to remove the effect.
|
||||||
|
*/
|
||||||
|
void CxImage::SetTransIndex(int32_t idx)
|
||||||
|
{
|
||||||
|
if (idx<(int32_t)head.biClrUsed)
|
||||||
|
info.nBkgndIndex = idx;
|
||||||
|
else
|
||||||
|
info.nBkgndIndex = 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the color used for transparency with 24 bpp images.
|
||||||
|
* You must call SetTransIndex(0) to enable the effect, SetTransIndex(-1) to disable it.
|
||||||
|
*/
|
||||||
|
void CxImage::SetTransColor(RGBQUAD rgb)
|
||||||
|
{
|
||||||
|
rgb.rgbReserved=0;
|
||||||
|
info.nBkgndColor = rgb;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::IsTransparent() const
|
||||||
|
{
|
||||||
|
return info.nBkgndIndex>=0; // <vho>
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns true if the image has 256 colors or less.
|
||||||
|
*/
|
||||||
|
bool CxImage::IsIndexed() const
|
||||||
|
{
|
||||||
|
return head.biClrUsed!=0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return 1 = indexed, 2 = RGB, 4 = RGBA
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::GetColorType()
|
||||||
|
{
|
||||||
|
uint8_t b = (uint8_t)((head.biBitCount>8) ? 2 /*COLORTYPE_COLOR*/ : 1 /*COLORTYPE_PALETTE*/);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (AlphaIsValid()) b = 4 /*COLORTYPE_ALPHA*/;
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return Resolution for TIFF, JPEG, PNG and BMP formats.
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetXDPI() const
|
||||||
|
{
|
||||||
|
return info.xDPI;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return Resolution for TIFF, JPEG, PNG and BMP formats.
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetYDPI() const
|
||||||
|
{
|
||||||
|
return info.yDPI;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Set resolution for TIFF, JPEG, PNG and BMP formats.
|
||||||
|
*/
|
||||||
|
void CxImage::SetXDPI(int32_t dpi)
|
||||||
|
{
|
||||||
|
if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI;
|
||||||
|
info.xDPI = dpi;
|
||||||
|
head.biXPelsPerMeter = (int32_t) floor(dpi * 10000.0 / 254.0 + 0.5);
|
||||||
|
if (pDib) ((BITMAPINFOHEADER*)pDib)->biXPelsPerMeter = head.biXPelsPerMeter;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Set resolution for TIFF, JPEG, PNG and BMP formats.
|
||||||
|
*/
|
||||||
|
void CxImage::SetYDPI(int32_t dpi)
|
||||||
|
{
|
||||||
|
if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI;
|
||||||
|
info.yDPI = dpi;
|
||||||
|
head.biYPelsPerMeter = (int32_t) floor(dpi * 10000.0 / 254.0 + 0.5);
|
||||||
|
if (pDib) ((BITMAPINFOHEADER*)pDib)->biYPelsPerMeter = head.biYPelsPerMeter;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa SetFlags
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetFlags() const
|
||||||
|
{
|
||||||
|
return info.dwFlags;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Image flags, for future use
|
||||||
|
* \param flags
|
||||||
|
* - 0x??00000 = reserved for 16 bit, CMYK, multilayer
|
||||||
|
* - 0x00??0000 = blend modes
|
||||||
|
* - 0x0000???? = layer id or user flags
|
||||||
|
*
|
||||||
|
* \param bLockReservedFlags protects the "reserved" and "blend modes" flags
|
||||||
|
*/
|
||||||
|
void CxImage::SetFlags(uint32_t flags, bool bLockReservedFlags)
|
||||||
|
{
|
||||||
|
if (bLockReservedFlags) info.dwFlags = flags & 0x0000ffff;
|
||||||
|
else info.dwFlags = flags;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa SetCodecOption
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetCodecOption(uint32_t imagetype)
|
||||||
|
{
|
||||||
|
imagetype = GetTypeIndexFromId(imagetype);
|
||||||
|
if (imagetype==0){
|
||||||
|
imagetype = GetTypeIndexFromId(GetType());
|
||||||
|
}
|
||||||
|
return info.dwCodecOpt[imagetype];
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Encode option for GIF, TIF, JPG, PNG and RAW
|
||||||
|
* - GIF : 0 = LZW (default), 1 = none, 2 = RLE.
|
||||||
|
* - TIF : 0 = automatic (default), or a valid compression code as defined in "tiff.h" (COMPRESSION_NONE = 1, COMPRESSION_CCITTRLE = 2, ...)
|
||||||
|
* - JPG : valid values stored in enum CODEC_OPTION ( ENCODE_BASELINE = 0x01, ENCODE_PROGRESSIVE = 0x10, ...)
|
||||||
|
* - PNG : combination of interlace option and compression option
|
||||||
|
* interlace option : 1 = interlace, 0 = no interlace
|
||||||
|
* compression option : 2 = no compression, 4 = best speed, 6 = best compression, 8 = default compression
|
||||||
|
* default is no interlace and default compression
|
||||||
|
* example : 5 = 1+4 = interlace + best speed
|
||||||
|
* - RAW : valid values stored in enum CODEC_OPTION ( DECODE_QUALITY_LIN = 0x00, DECODE_QUALITY_VNG = 0x01, ...)
|
||||||
|
*
|
||||||
|
* \return true if everything is ok
|
||||||
|
*/
|
||||||
|
bool CxImage::SetCodecOption(uint32_t opt, uint32_t imagetype)
|
||||||
|
{
|
||||||
|
imagetype = GetTypeIndexFromId(imagetype);
|
||||||
|
if (imagetype==0){
|
||||||
|
imagetype = GetTypeIndexFromId(GetType());
|
||||||
|
}
|
||||||
|
info.dwCodecOpt[imagetype] = opt;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return internal hDib object..
|
||||||
|
*/
|
||||||
|
void* CxImage::GetDIB() const
|
||||||
|
{
|
||||||
|
return pDib;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::GetHeight() const
|
||||||
|
{
|
||||||
|
return head.biHeight;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::GetWidth() const
|
||||||
|
{
|
||||||
|
return head.biWidth;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return uint32_t aligned width of the image.
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetEffWidth() const
|
||||||
|
{
|
||||||
|
return info.dwEffWidth;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return 2, 16, 256; 0 for RGB images.
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetNumColors() const
|
||||||
|
{
|
||||||
|
return head.biClrUsed;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return: 1, 4, 8, 24.
|
||||||
|
*/
|
||||||
|
uint16_t CxImage::GetBpp() const
|
||||||
|
{
|
||||||
|
return head.biBitCount;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return original image format
|
||||||
|
* \sa ENUM_CXIMAGE_FORMATS.
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetType() const
|
||||||
|
{
|
||||||
|
return info.dwType;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* change image format identifier
|
||||||
|
* \sa ENUM_CXIMAGE_FORMATS.
|
||||||
|
*/
|
||||||
|
bool CxImage::SetType(uint32_t type)
|
||||||
|
{
|
||||||
|
switch (type){
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
case CXIMAGE_FORMAT_BMP:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_GIF
|
||||||
|
case CXIMAGE_FORMAT_GIF:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
case CXIMAGE_FORMAT_JPG:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
case CXIMAGE_FORMAT_PNG:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
case CXIMAGE_FORMAT_MNG:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
case CXIMAGE_FORMAT_ICO:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
case CXIMAGE_FORMAT_TIF:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
case CXIMAGE_FORMAT_TGA:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
case CXIMAGE_FORMAT_PCX:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
case CXIMAGE_FORMAT_WBMP:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WMF
|
||||||
|
case CXIMAGE_FORMAT_WMF:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
case CXIMAGE_FORMAT_JBG:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
case CXIMAGE_FORMAT_JP2:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
case CXIMAGE_FORMAT_JPC:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
case CXIMAGE_FORMAT_PGX:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
case CXIMAGE_FORMAT_PNM:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
case CXIMAGE_FORMAT_RAS:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
case CXIMAGE_FORMAT_SKA:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
case CXIMAGE_FORMAT_RAW:
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PSD
|
||||||
|
case CXIMAGE_FORMAT_PSD:
|
||||||
|
#endif
|
||||||
|
info.dwType = type;
|
||||||
|
return true;
|
||||||
|
case CXIMAGE_FORMAT_UNKNOWN:
|
||||||
|
default:
|
||||||
|
info.dwType = CXIMAGE_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::GetNumTypes()
|
||||||
|
{
|
||||||
|
return CMAX_IMAGE_FORMATS-1;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::GetTypeIdFromName(const TCHAR* ext)
|
||||||
|
{
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
if (_tcsnicmp(ext,_T("bmp"),3)==0 ) return CXIMAGE_FORMAT_BMP;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
if (_tcsnicmp(ext,_T("jpg"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("jpe"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("jfi"),3)==0 ) return CXIMAGE_FORMAT_JPG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_GIF
|
||||||
|
if (_tcsnicmp(ext,_T("gif"),3)==0 ) return CXIMAGE_FORMAT_GIF;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
if (_tcsnicmp(ext,_T("png"),3)==0 ) return CXIMAGE_FORMAT_PNG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
if (_tcsnicmp(ext,_T("ico"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("cur"),3)==0 ) return CXIMAGE_FORMAT_ICO;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
if (_tcsnicmp(ext,_T("tif"),3)==0 ) return CXIMAGE_FORMAT_TIF;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
if (_tcsnicmp(ext,_T("tga"),3)==0 ) return CXIMAGE_FORMAT_TGA;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
if (_tcsnicmp(ext,_T("pcx"),3)==0 ) return CXIMAGE_FORMAT_PCX;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
if (_tcsnicmp(ext,_T("wbm"),3)==0 ) return CXIMAGE_FORMAT_WBMP;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WMF
|
||||||
|
if (_tcsnicmp(ext,_T("wmf"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("emf"),3)==0 ) return CXIMAGE_FORMAT_WMF;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
if (_tcsnicmp(ext,_T("jp2"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("j2k"),3)==0 ) return CXIMAGE_FORMAT_JP2;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
if (_tcsnicmp(ext,_T("jpc"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("j2c"),3)==0 ) return CXIMAGE_FORMAT_JPC;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
if (_tcsnicmp(ext,_T("pgx"),3)==0 ) return CXIMAGE_FORMAT_PGX;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
if (_tcsnicmp(ext,_T("ras"),3)==0 ) return CXIMAGE_FORMAT_RAS;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
if (_tcsnicmp(ext,_T("pnm"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("pgm"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("ppm"),3)==0 ) return CXIMAGE_FORMAT_PNM;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
if (_tcsnicmp(ext,_T("jbg"),3)==0 ) return CXIMAGE_FORMAT_JBG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
if (_tcsnicmp(ext,_T("mng"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("jng"),3)==0 ) return CXIMAGE_FORMAT_MNG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
if (_tcsnicmp(ext,_T("ska"),3)==0 ) return CXIMAGE_FORMAT_SKA;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PSD
|
||||||
|
if (_tcsnicmp(ext,_T("psd"),3)==0 ) return CXIMAGE_FORMAT_PSD;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
if (_tcsnicmp(ext,_T("nef"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("crw"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("cr2"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("dng"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("arw"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("erf"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("3fr"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("dcr"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("raw"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("x3f"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("mef"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("raf"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("mrw"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("pef"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("sr2"),3)==0 ||
|
||||||
|
_tcsnicmp(ext,_T("orf"),3)==0 ) return CXIMAGE_FORMAT_RAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return CXIMAGE_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::GetTypeIdFromIndex(const uint32_t index)
|
||||||
|
{
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
n=0; if (index == n) return CXIMAGE_FORMAT_UNKNOWN;
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_BMP;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_GIF
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_GIF;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_JPG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_PNG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_ICO;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_TIF;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_TGA;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_PCX;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_WBMP;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WMF
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_WMF;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_JP2;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_JPC;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_PGX;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_PNM;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_RAS;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_JBG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_MNG;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_SKA;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_RAW;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PSD
|
||||||
|
n++; if (index == n) return CXIMAGE_FORMAT_PSD;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return CXIMAGE_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::GetTypeIndexFromId(const uint32_t id)
|
||||||
|
{
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
n=0; if (id == CXIMAGE_FORMAT_UNKNOWN) return n;
|
||||||
|
#if CXIMAGE_SUPPORT_BMP
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_BMP) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_GIF
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_GIF) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_JPG) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_PNG) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ICO
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_ICO) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_TIF) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_TGA) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_PCX) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_WBMP) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_WMF
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_WMF) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_JP2) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_JPC) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_PGX) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_PNM) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_RAS) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_JBG) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_MNG) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_SKA) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_RAW) return n;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PSD
|
||||||
|
n++; if (id == CXIMAGE_FORMAT_PSD) return n;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return current frame delay in milliseconds. Only for GIF and MNG formats.
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetFrameDelay() const
|
||||||
|
{
|
||||||
|
return info.dwFrameDelay;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets current frame delay. Only for GIF format.
|
||||||
|
* \param d = delay in milliseconds
|
||||||
|
*/
|
||||||
|
void CxImage::SetFrameDelay(uint32_t d)
|
||||||
|
{
|
||||||
|
info.dwFrameDelay=d;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::GetOffset(int32_t *x,int32_t *y)
|
||||||
|
{
|
||||||
|
*x=info.xOffset;
|
||||||
|
*y=info.yOffset;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetOffset(int32_t x,int32_t y)
|
||||||
|
{
|
||||||
|
info.xOffset=x;
|
||||||
|
info.yOffset=y;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa SetJpegQuality, GetJpegQualityF
|
||||||
|
* \author [DP]; changes [Stefan Sch<63>rmans]
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::GetJpegQuality() const
|
||||||
|
{
|
||||||
|
return (uint8_t)(info.fQuality + 0.5f);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa SetJpegQuality, GetJpegQuality
|
||||||
|
* \author [Stefan Sch<63>rmans]
|
||||||
|
*/
|
||||||
|
float CxImage::GetJpegQualityF() const
|
||||||
|
{
|
||||||
|
return info.fQuality;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* quality level for JPEG and JPEG2000
|
||||||
|
* \param q: can be from 0 to 100
|
||||||
|
* \author [DP]; changes [Stefan Sch<63>rmans]
|
||||||
|
*/
|
||||||
|
void CxImage::SetJpegQuality(uint8_t q){
|
||||||
|
info.fQuality = (float)q;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* quality level for JPEG and JPEG2000
|
||||||
|
* necessary for JPEG2000 when quality is between 0.0 and 1.0
|
||||||
|
* \param q: can be from 0.0 to 100.0
|
||||||
|
* \author [Stefan Sch<63>rmans]
|
||||||
|
*/
|
||||||
|
void CxImage::SetJpegQualityF(float q){
|
||||||
|
if (q>0) info.fQuality = q;
|
||||||
|
else info.fQuality = 0.0f;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa SetJpegScale
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::GetJpegScale() const
|
||||||
|
{
|
||||||
|
return info.nJpegScale;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* scaling down during JPEG decoding valid numbers are 1, 2, 4, 8
|
||||||
|
* \author [ignacio]
|
||||||
|
*/
|
||||||
|
void CxImage::SetJpegScale(uint8_t q){
|
||||||
|
info.nJpegScale = q;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Used to monitor the slow loops.
|
||||||
|
* \return value is from 0 to 100.
|
||||||
|
* \sa SetProgress
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetProgress() const
|
||||||
|
{
|
||||||
|
return info.nProgress;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return the escape code.
|
||||||
|
* \sa SetEscape
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetEscape() const
|
||||||
|
{
|
||||||
|
return info.nEscape;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Forces the value of the internal progress variable.
|
||||||
|
* \param p should be from 0 to 100.
|
||||||
|
* \sa GetProgress
|
||||||
|
*/
|
||||||
|
void CxImage::SetProgress(int32_t p)
|
||||||
|
{
|
||||||
|
info.nProgress = p;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Used to quit the slow loops or the codecs.
|
||||||
|
* - SetEscape(-1) before Decode forces the function to exit, right after
|
||||||
|
* the image width and height are available ( for bmp, jpg, gif, tif )
|
||||||
|
*/
|
||||||
|
void CxImage::SetEscape(int32_t i)
|
||||||
|
{
|
||||||
|
info.nEscape = i;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the image is correctly initializated.
|
||||||
|
*/
|
||||||
|
bool CxImage::IsValid() const
|
||||||
|
{
|
||||||
|
return pDib!=0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* True if the image is enabled for painting.
|
||||||
|
*/
|
||||||
|
bool CxImage::IsEnabled() const
|
||||||
|
{
|
||||||
|
return info.bEnabled;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Enables/disables the image.
|
||||||
|
*/
|
||||||
|
void CxImage::Enable(bool enable)
|
||||||
|
{
|
||||||
|
info.bEnabled=enable;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* This function must be used after a Decode() / Load() call.
|
||||||
|
* Use the sequence SetFrame(-1); Load(...); GetNumFrames();
|
||||||
|
* to get the number of images without loading the first image.
|
||||||
|
* \return the number of images in the file.
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetNumFrames() const
|
||||||
|
{
|
||||||
|
return info.nNumFrames;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return the current selected image (zero-based index).
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetFrame() const
|
||||||
|
{
|
||||||
|
return info.nFrame;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the image number that the next Decode() / Load() call will load
|
||||||
|
*/
|
||||||
|
void CxImage::SetFrame(int32_t nFrame){
|
||||||
|
info.nFrame=nFrame;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the method for drawing the frame related to others
|
||||||
|
* \sa GetDisposalMethod
|
||||||
|
*/
|
||||||
|
void CxImage::SetDisposalMethod(uint8_t dm)
|
||||||
|
{ info.dispmeth=dm; }
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Gets the method for drawing the frame related to others
|
||||||
|
* Values : 0 - No disposal specified. The decoder is
|
||||||
|
* not required to take any action.
|
||||||
|
* 1 - Do not dispose. The graphic is to be left
|
||||||
|
* in place.
|
||||||
|
* 2 - Restore to background color. The area used by the
|
||||||
|
* graphic must be restored to the background color.
|
||||||
|
* 3 - Restore to previous. The decoder is required to
|
||||||
|
* restore the area overwritten by the graphic with
|
||||||
|
* what was there prior to rendering the graphic.
|
||||||
|
* 4-7 - To be defined.
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::GetDisposalMethod() const
|
||||||
|
{ return info.dispmeth; }
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::GetRetreiveAllFrames() const
|
||||||
|
{ return info.bGetAllFrames; }
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetRetreiveAllFrames(bool flag)
|
||||||
|
{ info.bGetAllFrames = flag; }
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImage * CxImage::GetFrame(int32_t nFrame) const
|
||||||
|
{
|
||||||
|
if ( ppFrames == NULL) return NULL;
|
||||||
|
if ( info.nNumFrames == 0) return NULL;
|
||||||
|
if ( nFrame >= info.nNumFrames ) return NULL;
|
||||||
|
if ( nFrame < 0) nFrame = info.nNumFrames - 1;
|
||||||
|
return ppFrames[nFrame];
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int16_t CxImage::m_ntohs(const int16_t word)
|
||||||
|
{
|
||||||
|
if (info.bLittleEndianHost) return word;
|
||||||
|
return ( (word & 0xff) << 8 ) | ( (word >> 8) & 0xff );
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int32_t CxImage::m_ntohl(const int32_t dword)
|
||||||
|
{
|
||||||
|
if (info.bLittleEndianHost) return dword;
|
||||||
|
return ((dword & 0xff) << 24 ) | ((dword & 0xff00) << 8 ) |
|
||||||
|
((dword >> 8) & 0xff00) | ((dword >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::bihtoh(BITMAPINFOHEADER* bih)
|
||||||
|
{
|
||||||
|
bih->biSize = m_ntohl(bih->biSize);
|
||||||
|
bih->biWidth = m_ntohl(bih->biWidth);
|
||||||
|
bih->biHeight = m_ntohl(bih->biHeight);
|
||||||
|
bih->biPlanes = m_ntohs(bih->biPlanes);
|
||||||
|
bih->biBitCount = m_ntohs(bih->biBitCount);
|
||||||
|
bih->biCompression = m_ntohl(bih->biCompression);
|
||||||
|
bih->biSizeImage = m_ntohl(bih->biSizeImage);
|
||||||
|
bih->biXPelsPerMeter = m_ntohl(bih->biXPelsPerMeter);
|
||||||
|
bih->biYPelsPerMeter = m_ntohl(bih->biYPelsPerMeter);
|
||||||
|
bih->biClrUsed = m_ntohl(bih->biClrUsed);
|
||||||
|
bih->biClrImportant = m_ntohl(bih->biClrImportant);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns the last reported error.
|
||||||
|
*/
|
||||||
|
const char* CxImage::GetLastError()
|
||||||
|
{
|
||||||
|
return info.szLastError;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::DumpSize()
|
||||||
|
{
|
||||||
|
uint32_t n;
|
||||||
|
n = sizeof(BITMAPINFOHEADER) + sizeof(CXIMAGEINFO) + GetSize();
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pAlpha){
|
||||||
|
n += 1 + head.biWidth * head.biHeight;
|
||||||
|
} else n++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
if (pSelection){
|
||||||
|
n += 1 + head.biWidth * head.biHeight;
|
||||||
|
} else n++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_LAYERS
|
||||||
|
if (ppLayers){
|
||||||
|
for (int32_t m=0; m<GetNumLayers(); m++){
|
||||||
|
if (GetLayer(m)){
|
||||||
|
n += 1 + GetLayer(m)->DumpSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else n++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ppFrames){
|
||||||
|
for (int32_t m=0; m<GetNumFrames(); m++){
|
||||||
|
if (GetFrame(m)){
|
||||||
|
n += 1 + GetFrame(m)->DumpSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else n++;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::Dump(uint8_t * dst)
|
||||||
|
{
|
||||||
|
if (!dst) return 0;
|
||||||
|
|
||||||
|
memcpy(dst,&head,sizeof(BITMAPINFOHEADER));
|
||||||
|
dst += sizeof(BITMAPINFOHEADER);
|
||||||
|
|
||||||
|
memcpy(dst,&info,sizeof(CXIMAGEINFO));
|
||||||
|
dst += sizeof(CXIMAGEINFO);
|
||||||
|
|
||||||
|
memcpy(dst,pDib,GetSize());
|
||||||
|
dst += GetSize();
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pAlpha){
|
||||||
|
memset(dst++, 1, 1);
|
||||||
|
memcpy(dst,pAlpha,head.biWidth * head.biHeight);
|
||||||
|
dst += head.biWidth * head.biHeight;
|
||||||
|
} else {
|
||||||
|
memset(dst++, 0, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
if (pSelection){
|
||||||
|
memset(dst++, 1, 1);
|
||||||
|
memcpy(dst,pSelection,head.biWidth * head.biHeight);
|
||||||
|
dst += head.biWidth * head.biHeight;
|
||||||
|
} else {
|
||||||
|
memset(dst++, 0, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_LAYERS
|
||||||
|
if (ppLayers){
|
||||||
|
memset(dst++, 1, 1);
|
||||||
|
for (int32_t m=0; m<GetNumLayers(); m++){
|
||||||
|
if (GetLayer(m)){
|
||||||
|
dst += GetLayer(m)->Dump(dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memset(dst++, 0, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ppFrames){
|
||||||
|
memset(dst++, 1, 1);
|
||||||
|
for (int32_t m=0; m<GetNumFrames(); m++){
|
||||||
|
if (GetFrame(m)){
|
||||||
|
dst += GetFrame(m)->Dump(dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memset(dst++, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DumpSize();
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint32_t CxImage::UnDump(const uint8_t * src)
|
||||||
|
{
|
||||||
|
if (!src)
|
||||||
|
return 0;
|
||||||
|
if (!Destroy())
|
||||||
|
return 0;
|
||||||
|
if (!DestroyFrames())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint32_t n = 0;
|
||||||
|
|
||||||
|
memcpy(&head,src,sizeof(BITMAPINFOHEADER));
|
||||||
|
n += sizeof(BITMAPINFOHEADER);
|
||||||
|
|
||||||
|
memcpy(&info,&src[n],sizeof(CXIMAGEINFO));
|
||||||
|
n += sizeof(CXIMAGEINFO);
|
||||||
|
|
||||||
|
if (!Create(head.biWidth, head.biHeight, head.biBitCount, info.dwType))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(pDib,&src[n],GetSize());
|
||||||
|
n += GetSize();
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (src[n++]){
|
||||||
|
if (AlphaCreate()){
|
||||||
|
memcpy(pAlpha, &src[n], head.biWidth * head.biHeight);
|
||||||
|
}
|
||||||
|
n += head.biWidth * head.biHeight;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
if (src[n++]){
|
||||||
|
RECT box = info.rSelectionBox;
|
||||||
|
if (SelectionCreate()){
|
||||||
|
info.rSelectionBox = box;
|
||||||
|
memcpy(pSelection, &src[n], head.biWidth * head.biHeight);
|
||||||
|
}
|
||||||
|
n += head.biWidth * head.biHeight;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_LAYERS
|
||||||
|
if (src[n++]){
|
||||||
|
ppLayers = new CxImage*[info.nNumLayers];
|
||||||
|
for (int32_t m=0; m<GetNumLayers(); m++){
|
||||||
|
ppLayers[m] = new CxImage();
|
||||||
|
n += ppLayers[m]->UnDump(&src[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (src[n++]){
|
||||||
|
ppFrames = new CxImage*[info.nNumFrames];
|
||||||
|
for (int32_t m=0; m<GetNumFrames(); m++){
|
||||||
|
ppFrames[m] = new CxImage();
|
||||||
|
n += ppFrames[m]->UnDump(&src[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \return A.BBCCCDDDD
|
||||||
|
* - A = main version
|
||||||
|
* - BB = main revision
|
||||||
|
* - CCC = minor revision (letter)
|
||||||
|
* - DDDD = experimental revision
|
||||||
|
*/
|
||||||
|
const float CxImage::GetVersionNumber()
|
||||||
|
{
|
||||||
|
return 7.000010000f;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const TCHAR* CxImage::GetVersion()
|
||||||
|
{
|
||||||
|
static const TCHAR CxImageVersion[] = _T("CxImage 7.0.1");
|
||||||
|
return (CxImageVersion);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
1045
Raw2Bmp_MFC/include/ximaint.cpp
Normal file
1045
Raw2Bmp_MFC/include/ximaint.cpp
Normal file
File diff suppressed because it is too large
Load Diff
253
Raw2Bmp_MFC/include/ximaiter.h
Normal file
253
Raw2Bmp_MFC/include/ximaiter.h
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
* File: ImaIter.h
|
||||||
|
* Purpose: Declaration of the Platform Independent Image Base Class
|
||||||
|
* Author: Alejandro Aguilar Sierra
|
||||||
|
* Created: 1995
|
||||||
|
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
|
||||||
|
*
|
||||||
|
* 07/08/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* - removed slow loops
|
||||||
|
* - added safe checks
|
||||||
|
*
|
||||||
|
* Permission is given by the author to freely redistribute and include
|
||||||
|
* this code in any program as int32_t as this credit is given where due.
|
||||||
|
*
|
||||||
|
* COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
|
||||||
|
* THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
|
||||||
|
* OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
|
||||||
|
* CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
|
||||||
|
* THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
|
||||||
|
* SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
|
||||||
|
* PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
|
||||||
|
* THIS DISCLAIMER.
|
||||||
|
*
|
||||||
|
* Use at your own risk!
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__ImaIter_h)
|
||||||
|
#define __ImaIter_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
#include "ximadef.h"
|
||||||
|
|
||||||
|
class CImageIterator
|
||||||
|
{
|
||||||
|
friend class CxImage;
|
||||||
|
protected:
|
||||||
|
int32_t Itx, Ity; // Counters
|
||||||
|
int32_t Stepx, Stepy;
|
||||||
|
uint8_t* IterImage; // Image pointer
|
||||||
|
CxImage *ima;
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
CImageIterator ( void );
|
||||||
|
CImageIterator ( CxImage *image );
|
||||||
|
operator CxImage* ();
|
||||||
|
|
||||||
|
// Iterators
|
||||||
|
BOOL ItOK ();
|
||||||
|
void Reset ();
|
||||||
|
void Upset ();
|
||||||
|
void SetRow(uint8_t *buf, int32_t n);
|
||||||
|
void GetRow(uint8_t *buf, int32_t n);
|
||||||
|
uint8_t GetByte( ) { return IterImage[Itx]; }
|
||||||
|
void SetByte(uint8_t b) { IterImage[Itx] = b; }
|
||||||
|
uint8_t* GetRow(void);
|
||||||
|
uint8_t* GetRow(int32_t n);
|
||||||
|
BOOL NextRow();
|
||||||
|
BOOL PrevRow();
|
||||||
|
BOOL NextByte();
|
||||||
|
BOOL PrevByte();
|
||||||
|
|
||||||
|
void SetSteps(int32_t x, int32_t y=0) { Stepx = x; Stepy = y; }
|
||||||
|
void GetSteps(int32_t *x, int32_t *y) { *x = Stepx; *y = Stepy; }
|
||||||
|
BOOL NextStep();
|
||||||
|
BOOL PrevStep();
|
||||||
|
|
||||||
|
void SetY(int32_t y); /* AD - for interlace */
|
||||||
|
int32_t GetY() {return Ity;}
|
||||||
|
BOOL GetCol(uint8_t* pCol, uint32_t x);
|
||||||
|
BOOL SetCol(uint8_t* pCol, uint32_t x);
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline
|
||||||
|
CImageIterator::CImageIterator(void)
|
||||||
|
{
|
||||||
|
ima = 0;
|
||||||
|
IterImage = 0;
|
||||||
|
Itx = Ity = 0;
|
||||||
|
Stepx = Stepy = 0;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline
|
||||||
|
CImageIterator::CImageIterator(CxImage *imageImpl): ima(imageImpl)
|
||||||
|
{
|
||||||
|
if (ima) IterImage = ima->GetBits();
|
||||||
|
Itx = Ity = 0;
|
||||||
|
Stepx = Stepy = 0;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline
|
||||||
|
CImageIterator::operator CxImage* ()
|
||||||
|
{
|
||||||
|
return ima;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::ItOK ()
|
||||||
|
{
|
||||||
|
if (ima) return ima->IsInside(Itx, Ity);
|
||||||
|
else return FALSE;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline void CImageIterator::Reset()
|
||||||
|
{
|
||||||
|
if (ima) IterImage = ima->GetBits();
|
||||||
|
else IterImage=0;
|
||||||
|
Itx = Ity = 0;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline void CImageIterator::Upset()
|
||||||
|
{
|
||||||
|
Itx = 0;
|
||||||
|
Ity = ima->GetHeight()-1;
|
||||||
|
IterImage = ima->GetBits() + ima->GetEffWidth()*(ima->GetHeight()-1);
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::NextRow()
|
||||||
|
{
|
||||||
|
if (++Ity >= (int32_t)ima->GetHeight()) return 0;
|
||||||
|
IterImage += ima->GetEffWidth();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::PrevRow()
|
||||||
|
{
|
||||||
|
if (--Ity < 0) return 0;
|
||||||
|
IterImage -= ima->GetEffWidth();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* AD - for interlace */
|
||||||
|
inline void CImageIterator::SetY(int32_t y)
|
||||||
|
{
|
||||||
|
if ((y < 0) || (y > (int32_t)ima->GetHeight())) return;
|
||||||
|
Ity = y;
|
||||||
|
IterImage = ima->GetBits() + ima->GetEffWidth()*y;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline void CImageIterator::SetRow(uint8_t *buf, int32_t n)
|
||||||
|
{
|
||||||
|
if (n<0) n = (int32_t)ima->GetEffWidth();
|
||||||
|
else n = min(n,(int32_t)ima->GetEffWidth());
|
||||||
|
|
||||||
|
if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(IterImage,buf,n);
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline void CImageIterator::GetRow(uint8_t *buf, int32_t n)
|
||||||
|
{
|
||||||
|
if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0))
|
||||||
|
memcpy(buf,IterImage,min(n,(int32_t)ima->GetEffWidth()));
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline uint8_t* CImageIterator::GetRow()
|
||||||
|
{
|
||||||
|
return IterImage;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline uint8_t* CImageIterator::GetRow(int32_t n)
|
||||||
|
{
|
||||||
|
SetY(n);
|
||||||
|
return IterImage;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::NextByte()
|
||||||
|
{
|
||||||
|
if (++Itx < (int32_t)ima->GetEffWidth()) return 1;
|
||||||
|
else
|
||||||
|
if (++Ity < (int32_t)ima->GetHeight()){
|
||||||
|
IterImage += ima->GetEffWidth();
|
||||||
|
Itx = 0;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::PrevByte()
|
||||||
|
{
|
||||||
|
if (--Itx >= 0) return 1;
|
||||||
|
else
|
||||||
|
if (--Ity >= 0){
|
||||||
|
IterImage -= ima->GetEffWidth();
|
||||||
|
Itx = 0;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::NextStep()
|
||||||
|
{
|
||||||
|
Itx += Stepx;
|
||||||
|
if (Itx < (int32_t)ima->GetEffWidth()) return 1;
|
||||||
|
else {
|
||||||
|
Ity += Stepy;
|
||||||
|
if (Ity < (int32_t)ima->GetHeight()){
|
||||||
|
IterImage += ima->GetEffWidth();
|
||||||
|
Itx = 0;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::PrevStep()
|
||||||
|
{
|
||||||
|
Itx -= Stepx;
|
||||||
|
if (Itx >= 0) return 1;
|
||||||
|
else {
|
||||||
|
Ity -= Stepy;
|
||||||
|
if (Ity >= 0 && Ity < (int32_t)ima->GetHeight()) {
|
||||||
|
IterImage -= ima->GetEffWidth();
|
||||||
|
Itx = 0;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::GetCol(uint8_t* pCol, uint32_t x)
|
||||||
|
{
|
||||||
|
if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
|
||||||
|
return 0;
|
||||||
|
uint32_t h = ima->GetHeight();
|
||||||
|
//uint32_t line = ima->GetEffWidth();
|
||||||
|
uint8_t bytes = (uint8_t)(ima->GetBpp()>>3);
|
||||||
|
uint8_t* pSrc;
|
||||||
|
for (uint32_t y=0;y<h;y++){
|
||||||
|
pSrc = ima->GetBits(y) + x*bytes;
|
||||||
|
for (uint8_t w=0;w<bytes;w++){
|
||||||
|
*pCol++=*pSrc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
inline BOOL CImageIterator::SetCol(uint8_t* pCol, uint32_t x)
|
||||||
|
{
|
||||||
|
if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
|
||||||
|
return 0;
|
||||||
|
uint32_t h = ima->GetHeight();
|
||||||
|
//uint32_t line = ima->GetEffWidth();
|
||||||
|
uint8_t bytes = (uint8_t)(ima->GetBpp()>>3);
|
||||||
|
uint8_t* pSrc;
|
||||||
|
for (uint32_t y=0;y<h;y++){
|
||||||
|
pSrc = ima->GetBits(y) + x*bytes;
|
||||||
|
for (uint8_t w=0;w<bytes;w++){
|
||||||
|
*pSrc++=*pCol++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
#endif
|
||||||
325
Raw2Bmp_MFC/include/ximajas.cpp
Normal file
325
Raw2Bmp_MFC/include/ximajas.cpp
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
/*
|
||||||
|
* File: ximajas.cpp
|
||||||
|
* Purpose: Platform Independent JasPer Image Class Loader and Writer
|
||||||
|
* 12/Apr/2003 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximajas.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JASPER
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJAS::Decode(CxFile *hFile, uint32_t imagetype)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
jas_image_t *image=0;
|
||||||
|
jas_stream_t *in=0;
|
||||||
|
jas_matrix_t **bufs=0;
|
||||||
|
int32_t i,error=0;
|
||||||
|
int32_t fmt;
|
||||||
|
//jas_setdbglevel(0);
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (jas_init())
|
||||||
|
cx_throw("cannot initialize jasper");
|
||||||
|
|
||||||
|
in = jas_stream_fdopen(0, "rb");
|
||||||
|
if (!in)
|
||||||
|
cx_throw("error: cannot open standard input");
|
||||||
|
|
||||||
|
CxFileJas src(hFile,in);
|
||||||
|
|
||||||
|
fmt = jas_image_getfmt(in);
|
||||||
|
if (fmt<0)
|
||||||
|
cx_throw("error: unknowm format");
|
||||||
|
|
||||||
|
image = jas_image_decode(in, fmt, 0);
|
||||||
|
if (!image){
|
||||||
|
fmt = -1;
|
||||||
|
cx_throw("error: cannot load image data");
|
||||||
|
}
|
||||||
|
|
||||||
|
char szfmt[4];
|
||||||
|
*szfmt = '\0';
|
||||||
|
strncpy(szfmt,jas_image_fmttostr(fmt),3);
|
||||||
|
szfmt[3] = '\0';
|
||||||
|
|
||||||
|
fmt = -1;
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
if (strcmp(szfmt,"jp2")==0) fmt = CXIMAGE_FORMAT_JP2;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
if (strcmp(szfmt,"jpc")==0) fmt = CXIMAGE_FORMAT_JPC;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
if (strcmp(szfmt,"ras")==0) fmt = CXIMAGE_FORMAT_RAS;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
if (strcmp(szfmt,"pnm")==0) fmt = CXIMAGE_FORMAT_PNM;
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
if (strcmp(szfmt,"pgx")==0) fmt = CXIMAGE_FORMAT_PGX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//if (fmt<0)
|
||||||
|
// cx_throw("error: unknowm format");
|
||||||
|
|
||||||
|
int32_t x,y,w,h,depth,cmptno;
|
||||||
|
|
||||||
|
w = jas_image_cmptwidth(image,0);
|
||||||
|
h = jas_image_cmptheight(image,0);
|
||||||
|
depth = jas_image_cmptprec(image,0);
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = w;
|
||||||
|
head.biHeight= h;
|
||||||
|
info.dwType = fmt<0 ? 0 : fmt;
|
||||||
|
cx_throw("output dimensions returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image->numcmpts_ > 64 || image->numcmpts_ < 0)
|
||||||
|
cx_throw("error: too many components");
|
||||||
|
|
||||||
|
// <LD> 01/Jan/2005: Always force conversion to sRGB. Seems to be required for many types of JPEG2000 file.
|
||||||
|
// if (depth!=1 && depth!=4 && depth!=8)
|
||||||
|
if (image->numcmpts_>=3 && depth <=8)
|
||||||
|
{
|
||||||
|
jas_image_t *newimage;
|
||||||
|
jas_cmprof_t *outprof;
|
||||||
|
//jas_eprintf("forcing conversion to sRGB\n");
|
||||||
|
outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB);
|
||||||
|
if (!outprof) {
|
||||||
|
cx_throw("cannot create sRGB profile");
|
||||||
|
}
|
||||||
|
newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER);
|
||||||
|
if (!newimage) {
|
||||||
|
jas_cmprof_destroy(outprof); // <LD> 01/Jan/2005: Destroy color profile on error.
|
||||||
|
cx_throw("cannot convert to sRGB");
|
||||||
|
}
|
||||||
|
jas_image_destroy(image);
|
||||||
|
jas_cmprof_destroy(outprof);
|
||||||
|
image = newimage;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufs = (jas_matrix_t **)calloc(image->numcmpts_, sizeof(jas_matrix_t**));
|
||||||
|
for (i = 0; i < image->numcmpts_; ++i) {
|
||||||
|
bufs[i] = jas_matrix_create(1, w);
|
||||||
|
if (!bufs[i]) {
|
||||||
|
cx_throw("error: cannot allocate memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t nshift = (depth>8) ? (depth-8) : 0;
|
||||||
|
|
||||||
|
if (image->numcmpts_==3 &&
|
||||||
|
image->cmpts_[0]->width_ == image->cmpts_[1]->width_ &&
|
||||||
|
image->cmpts_[1]->width_ == image->cmpts_[2]->width_ &&
|
||||||
|
image->cmpts_[0]->height_ == image->cmpts_[1]->height_ &&
|
||||||
|
image->cmpts_[1]->height_ == image->cmpts_[2]->height_ &&
|
||||||
|
image->cmpts_[0]->prec_ == image->cmpts_[1]->prec_ &&
|
||||||
|
image->cmpts_[1]->prec_ == image->cmpts_[2]->prec_ )
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!Create(w,h,24,fmt))
|
||||||
|
cx_throw("");
|
||||||
|
|
||||||
|
RGBQUAD c;
|
||||||
|
for (y=0; y<h; y++) {
|
||||||
|
for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
|
||||||
|
jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[cmptno]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x=0; x<w; x++){
|
||||||
|
c.rgbRed = (uint8_t)((jas_matrix_getv(bufs[0], x)>>nshift));
|
||||||
|
c.rgbGreen = (uint8_t)((jas_matrix_getv(bufs[1], x)>>nshift));
|
||||||
|
c.rgbBlue = (uint8_t)((jas_matrix_getv(bufs[2], x)>>nshift));
|
||||||
|
SetPixelColor(x,h-1-y,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info.nNumFrames = image->numcmpts_;
|
||||||
|
if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){
|
||||||
|
cx_throw("wrong frame!");
|
||||||
|
}
|
||||||
|
for (cmptno=0; cmptno<=info.nFrame; cmptno++) {
|
||||||
|
w = jas_image_cmptwidth(image,cmptno);
|
||||||
|
h = jas_image_cmptheight(image,cmptno);
|
||||||
|
depth = jas_image_cmptprec(image,cmptno);
|
||||||
|
if (depth>8) depth=8;
|
||||||
|
if(!Create(w,h,depth,imagetype))
|
||||||
|
cx_throw("");
|
||||||
|
SetGrayPalette();
|
||||||
|
for (y=0; y<h; y++) {
|
||||||
|
jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[0]);
|
||||||
|
for (x=0; x<w; x++){
|
||||||
|
SetPixelIndex(x,h-1-y,(uint8_t)((jas_matrix_getv(bufs[0], x)>>nshift)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (info.nEscape == -1 && fmt>0){
|
||||||
|
error = 0;
|
||||||
|
} else {
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufs) {
|
||||||
|
for (i = 0; i < image->numcmpts_; ++i){ if (bufs[i]) jas_matrix_destroy(bufs[i]);}
|
||||||
|
free(bufs);
|
||||||
|
}
|
||||||
|
jas_cleanup();
|
||||||
|
if (image) jas_image_destroy(image);
|
||||||
|
if (in) jas_stream_close(in);
|
||||||
|
return (error==0);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJAS::Encode(CxFile * hFile, uint32_t imagetype)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
if (head.biClrUsed!=0 && !IsGrayScale()){
|
||||||
|
strcpy(info.szLastError,"JasPer can save only RGB or GrayScale images");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jas_image_t *image=0;
|
||||||
|
jas_stream_t *out=0;
|
||||||
|
jas_matrix_t *cmpts[3];
|
||||||
|
int32_t x,y,yflip,error=0;
|
||||||
|
uint_fast16_t cmptno, numcmpts=0;
|
||||||
|
jas_image_cmptparm_t cmptparms[3], *cmptparm;
|
||||||
|
|
||||||
|
cx_try {
|
||||||
|
|
||||||
|
if (jas_init())
|
||||||
|
cx_throw("cannot initialize jasper");
|
||||||
|
|
||||||
|
out = jas_stream_fdopen(0, "wb");
|
||||||
|
if (!out)
|
||||||
|
cx_throw("error: cannot open standard output");
|
||||||
|
|
||||||
|
CxFileJas src(hFile,out);
|
||||||
|
|
||||||
|
numcmpts = head.biClrUsed==0 ? 3 : 1;
|
||||||
|
|
||||||
|
for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, ++cmptparm) {
|
||||||
|
cmptparm->tlx = 0;
|
||||||
|
cmptparm->tly = 0;
|
||||||
|
cmptparm->hstep = 1;
|
||||||
|
cmptparm->vstep = 1;
|
||||||
|
cmptparm->width = head.biWidth;
|
||||||
|
cmptparm->height = head.biHeight;
|
||||||
|
cmptparm->prec = 8;
|
||||||
|
cmptparm->sgnd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create image object. */
|
||||||
|
image = jas_image_create(numcmpts, cmptparms, JAS_CLRSPC_UNKNOWN);
|
||||||
|
if (!image)
|
||||||
|
cx_throw("error : jas_image_create");
|
||||||
|
|
||||||
|
if (numcmpts == 3) {
|
||||||
|
jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
|
||||||
|
jas_image_setcmpttype(image, 0,
|
||||||
|
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
|
||||||
|
jas_image_setcmpttype(image, 1,
|
||||||
|
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
|
||||||
|
jas_image_setcmpttype(image, 2,
|
||||||
|
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
|
||||||
|
} else {
|
||||||
|
jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
|
||||||
|
jas_image_setcmpttype(image, 0,
|
||||||
|
JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (x = 0; x < numcmpts; ++x) { cmpts[x] = 0; }
|
||||||
|
/* Create temporary matrices to hold component data. */
|
||||||
|
for (x = 0; x < numcmpts; ++x) {
|
||||||
|
cmpts[x] = jas_matrix_create(1, head.biWidth);
|
||||||
|
if (!cmpts[x]) {
|
||||||
|
cx_throw("error : can't allocate memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RGBQUAD c;
|
||||||
|
for (y = 0; y < head.biHeight; ++y) {
|
||||||
|
for (x = 0; x < head.biWidth; ++x) {
|
||||||
|
if (head.biClrUsed==0){
|
||||||
|
c = GetPixelColor(x,y);
|
||||||
|
jas_matrix_setv(cmpts[0], x, c.rgbRed);
|
||||||
|
jas_matrix_setv(cmpts[1], x, c.rgbGreen);
|
||||||
|
jas_matrix_setv(cmpts[2], x, c.rgbBlue);
|
||||||
|
} else {
|
||||||
|
jas_matrix_setv(cmpts[0], x, GetPixelIndex(x,y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yflip = head.biHeight - 1 - y;
|
||||||
|
for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
|
||||||
|
if (jas_image_writecmpt(image, cmptno, 0, yflip, head.biWidth, 1, cmpts[cmptno])) {
|
||||||
|
cx_throw("error : jas_image_writecmpt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char szfmt[4];
|
||||||
|
*szfmt = '\0';
|
||||||
|
#if CXIMAGE_SUPPORT_JP2
|
||||||
|
if (imagetype == CXIMAGE_FORMAT_JP2) strcpy(szfmt,"jp2");
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_JPC
|
||||||
|
if (imagetype == CXIMAGE_FORMAT_JPC) strcpy(szfmt,"jpc");
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_RAS
|
||||||
|
if (imagetype == CXIMAGE_FORMAT_RAS) strcpy(szfmt,"ras");
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PNM
|
||||||
|
if (imagetype == CXIMAGE_FORMAT_PNM) strcpy(szfmt,"pnm");
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_PGX
|
||||||
|
if (imagetype == CXIMAGE_FORMAT_PGX){
|
||||||
|
strcpy(szfmt,"pgx");
|
||||||
|
if (head.biClrUsed==0) cx_throw("PGX can save only GrayScale images");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int32_t outfmt = jas_image_strtofmt(szfmt);
|
||||||
|
|
||||||
|
char szoutopts[32];
|
||||||
|
sprintf(szoutopts,"rate=%.3f", info.fQuality/100.0f);
|
||||||
|
|
||||||
|
if (jas_image_encode(image, out, outfmt, szoutopts)) {
|
||||||
|
cx_throw("error: cannot encode image");
|
||||||
|
}
|
||||||
|
jas_stream_flush(out);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; x < numcmpts; ++x) { if (cmpts[x]) { jas_matrix_destroy(cmpts[x]); } }
|
||||||
|
jas_cleanup();
|
||||||
|
if (image) jas_image_destroy(image);
|
||||||
|
if (out) jas_stream_close(out);
|
||||||
|
|
||||||
|
return (error==0);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_JASPER
|
||||||
|
|
||||||
88
Raw2Bmp_MFC/include/ximajas.h
Normal file
88
Raw2Bmp_MFC/include/ximajas.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* File: ximajas.h
|
||||||
|
* Purpose: Jasper Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageJAS (c) 12/Apr/2003 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* based on JasPer Copyright (c) 2001-2003 Michael David Adams - All rights reserved.
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaJAS_h)
|
||||||
|
#define __ximaJAS_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JASPER
|
||||||
|
|
||||||
|
#ifdef _LINUX
|
||||||
|
#include <jasper/jasper.h>
|
||||||
|
#else
|
||||||
|
#include "../jasper/include/jasper/jasper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CxImageJAS: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImageJAS(): CxImage((uint32_t)0) {} // <vho> cast to uint32_t
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,0);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,0);}
|
||||||
|
bool Decode(CxFile * hFile, uint32_t imagetype = 0);
|
||||||
|
bool Decode(FILE *hFile, uint32_t imagetype = 0) { CxIOFile file(hFile); return Decode(&file,imagetype); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile, uint32_t imagetype = 0);
|
||||||
|
bool Encode(FILE *hFile, uint32_t imagetype = 0) { CxIOFile file(hFile); return Encode(&file,imagetype); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
protected:
|
||||||
|
|
||||||
|
class CxFileJas
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxFileJas(CxFile* pFile,jas_stream_t *stream)
|
||||||
|
{
|
||||||
|
if (stream->obj_) jas_free(stream->obj_);
|
||||||
|
stream->obj_ = pFile;
|
||||||
|
|
||||||
|
// <vho> - cannot set the stream->ops_->functions here,
|
||||||
|
// because this overwrites a static structure in the Jasper library.
|
||||||
|
// This structure is used by Jasper for internal operations too, e.g. tempfile.
|
||||||
|
// However the ops_ pointer in the stream can be overwritten.
|
||||||
|
|
||||||
|
//stream->ops_->close_ = JasClose;
|
||||||
|
//stream->ops_->read_ = JasRead;
|
||||||
|
//stream->ops_->seek_ = JasSeek;
|
||||||
|
//stream->ops_->write_ = JasWrite;
|
||||||
|
|
||||||
|
jas_stream_CxFile.close_ = JasClose;
|
||||||
|
jas_stream_CxFile.read_ = JasRead;
|
||||||
|
jas_stream_CxFile.seek_ = JasSeek;
|
||||||
|
jas_stream_CxFile.write_ = JasWrite;
|
||||||
|
|
||||||
|
stream->ops_ = &jas_stream_CxFile;
|
||||||
|
|
||||||
|
// <vho> - end
|
||||||
|
}
|
||||||
|
static int32_t JasRead(jas_stream_obj_t *obj, char *buf, int32_t cnt)
|
||||||
|
{ return ((CxFile*)obj)->Read(buf,1,cnt); }
|
||||||
|
static int32_t JasWrite(jas_stream_obj_t *obj, char *buf, int32_t cnt)
|
||||||
|
{ return ((CxFile*)obj)->Write(buf,1,cnt); }
|
||||||
|
static long JasSeek(jas_stream_obj_t *obj, long offset, int32_t origin)
|
||||||
|
{ return ((CxFile*)obj)->Seek(offset,origin); }
|
||||||
|
static int32_t JasClose(jas_stream_obj_t * /*obj*/)
|
||||||
|
{ return 1; }
|
||||||
|
|
||||||
|
// <vho>
|
||||||
|
private:
|
||||||
|
jas_stream_ops_t jas_stream_CxFile;
|
||||||
|
// <vho> - end
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
174
Raw2Bmp_MFC/include/ximajbg.cpp
Normal file
174
Raw2Bmp_MFC/include/ximajbg.cpp
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* File: ximajbg.cpp
|
||||||
|
* Purpose: Platform Independent JBG Image Class Loader and Writer
|
||||||
|
* 18/Aug/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximajbg.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
|
||||||
|
#include "ximaiter.h"
|
||||||
|
|
||||||
|
#define JBIG_BUFSIZE 8192
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJBG::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
struct jbg_dec_state jbig_state;
|
||||||
|
uint32_t xmax = 4294967295UL, ymax = 4294967295UL;
|
||||||
|
uint32_t len, cnt;
|
||||||
|
uint8_t *buffer=0,*p;
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
jbg_dec_init(&jbig_state);
|
||||||
|
jbg_dec_maxsize(&jbig_state, xmax, ymax);
|
||||||
|
|
||||||
|
buffer = (uint8_t*)malloc(JBIG_BUFSIZE);
|
||||||
|
if (!buffer) cx_throw("Sorry, not enough memory available!");
|
||||||
|
|
||||||
|
result = JBG_EAGAIN;
|
||||||
|
do {
|
||||||
|
len = hFile->Read(buffer, 1, JBIG_BUFSIZE);
|
||||||
|
if (!len) break;
|
||||||
|
cnt = 0;
|
||||||
|
p = buffer;
|
||||||
|
while (len > 0 && (result == JBG_EAGAIN || result == JBG_EOK)) {
|
||||||
|
result = jbg_dec_in(&jbig_state, p, len, &cnt);
|
||||||
|
p += cnt;
|
||||||
|
len -= cnt;
|
||||||
|
}
|
||||||
|
} while (result == JBG_EAGAIN || result == JBG_EOK);
|
||||||
|
|
||||||
|
if (hFile->Error())
|
||||||
|
cx_throw("Problem while reading input file");
|
||||||
|
if (result != JBG_EOK && result != JBG_EOK_INTR)
|
||||||
|
cx_throw("Problem with input file");
|
||||||
|
|
||||||
|
int32_t w, h, bpp, planes, ew;
|
||||||
|
|
||||||
|
w = jbg_dec_getwidth(&jbig_state);
|
||||||
|
h = jbg_dec_getheight(&jbig_state);
|
||||||
|
planes = jbg_dec_getplanes(&jbig_state);
|
||||||
|
bpp = (planes+7)>>3;
|
||||||
|
ew = (w + 7)>>3;
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = w;
|
||||||
|
head.biHeight= h;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_JBG;
|
||||||
|
cx_throw("output dimensions returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (planes){
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
uint8_t* binary_image = jbg_dec_getimage(&jbig_state, 0);
|
||||||
|
|
||||||
|
if (!Create(w,h,1,CXIMAGE_FORMAT_JBG))
|
||||||
|
cx_throw("");
|
||||||
|
|
||||||
|
SetPaletteColor(0,255,255,255);
|
||||||
|
SetPaletteColor(1,0,0,0);
|
||||||
|
|
||||||
|
CImageIterator iter(this);
|
||||||
|
iter.Upset();
|
||||||
|
for (int32_t i=0;i<h;i++){
|
||||||
|
iter.SetRow(binary_image+i*ew,ew);
|
||||||
|
iter.PrevRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cx_throw("cannot decode images with more than 1 plane");
|
||||||
|
}
|
||||||
|
|
||||||
|
jbg_dec_free(&jbig_state);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
jbg_dec_free(&jbig_state);
|
||||||
|
if (buffer) free(buffer);
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_JBG) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJBG::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
if (head.biBitCount != 1){
|
||||||
|
strcpy(info.szLastError,"JBG can save only 1-bpp images");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t w, h, bpp, planes, ew, i, j, x, y;
|
||||||
|
|
||||||
|
w = head.biWidth;
|
||||||
|
h = head.biHeight;
|
||||||
|
planes = 1;
|
||||||
|
bpp = (planes+7)>>3;
|
||||||
|
ew = (w + 7)>>3;
|
||||||
|
|
||||||
|
uint8_t mask;
|
||||||
|
RGBQUAD *rgb = GetPalette();
|
||||||
|
if (CompareColors(&rgb[0],&rgb[1])<0) mask=255; else mask=0;
|
||||||
|
|
||||||
|
uint8_t *buffer = (uint8_t*)malloc(ew*h*2);
|
||||||
|
if (!buffer) {
|
||||||
|
strcpy(info.szLastError,"Sorry, not enough memory available!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y=0; y<h; y++){
|
||||||
|
i= y*ew;
|
||||||
|
j= (h-y-1)*info.dwEffWidth;
|
||||||
|
for (x=0; x<ew; x++){
|
||||||
|
buffer[i + x]=info.pImage[j + x]^mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct jbg_enc_state jbig_state;
|
||||||
|
jbg_enc_init(&jbig_state, w, h, planes, &buffer, jbig_data_out, hFile);
|
||||||
|
|
||||||
|
//jbg_enc_layers(&jbig_state, 2);
|
||||||
|
//jbg_enc_lrlmax(&jbig_state, 800, 600);
|
||||||
|
|
||||||
|
// Specify a few other options (each is ignored if negative)
|
||||||
|
int32_t dl = -1, dh = -1, d = -1, l0 = -1, mx = -1;
|
||||||
|
int32_t options = JBG_TPDON | JBG_TPBON | JBG_DPON;
|
||||||
|
int32_t order = JBG_ILEAVE | JBG_SMID;
|
||||||
|
jbg_enc_lrange(&jbig_state, dl, dh);
|
||||||
|
jbg_enc_options(&jbig_state, order, options, l0, mx, -1);
|
||||||
|
|
||||||
|
// now encode everything and send it to data_out()
|
||||||
|
jbg_enc_out(&jbig_state);
|
||||||
|
|
||||||
|
// give encoder a chance to free its temporary data structures
|
||||||
|
jbg_enc_free(&jbig_state);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
if (hFile->Error()){
|
||||||
|
strcpy(info.szLastError,"Problem while writing JBG file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_JBG
|
||||||
|
|
||||||
44
Raw2Bmp_MFC/include/ximajbg.h
Normal file
44
Raw2Bmp_MFC/include/ximajbg.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* File: ximajbg.h
|
||||||
|
* Purpose: JBG Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageJBG (c) 18/Aug/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* based on LIBJBG Copyright (c) 2002, Markus Kuhn - All rights reserved.
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaJBG_h)
|
||||||
|
#define __ximaJBG_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JBG
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "../jbig/jbig.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
class CxImageJBG: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImageJBG(): CxImage(CXIMAGE_FORMAT_JBG) {}
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JBG);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JBG);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
protected:
|
||||||
|
static void jbig_data_out(uint8_t *buffer, uint32_t len, void *file)
|
||||||
|
{((CxFile*)file)->Write(buffer,len,1);}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
542
Raw2Bmp_MFC/include/ximajpg.cpp
Normal file
542
Raw2Bmp_MFC/include/ximajpg.cpp
Normal file
@@ -0,0 +1,542 @@
|
|||||||
|
/*
|
||||||
|
* File: ximajpg.cpp
|
||||||
|
* Purpose: Platform Independent JPEG Image Class Loader and Writer
|
||||||
|
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximajpg.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
|
||||||
|
#ifdef _LINUX
|
||||||
|
#include <jmorecfg.h>
|
||||||
|
#else
|
||||||
|
#include "../jpeg/jmorecfg.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ximaiter.h"
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
struct jpg_error_mgr {
|
||||||
|
struct jpeg_error_mgr pub; /* "public" fields */
|
||||||
|
jmp_buf setjmp_buffer; /* for return to caller */
|
||||||
|
char* buffer; /* error message <CSC>*/
|
||||||
|
};
|
||||||
|
typedef jpg_error_mgr *jpg_error_ptr;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Here's the routine that will replace the standard error_exit method:
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static void
|
||||||
|
ima_jpeg_error_exit (j_common_ptr cinfo)
|
||||||
|
{
|
||||||
|
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
|
||||||
|
jpg_error_ptr myerr = (jpg_error_ptr) cinfo->err;
|
||||||
|
/* Create the message */
|
||||||
|
myerr->pub.format_message (cinfo, myerr->buffer);
|
||||||
|
/* Send it to stderr, adding a newline */
|
||||||
|
/* Return control to the setjmp point */
|
||||||
|
longjmp(myerr->setjmp_buffer, 1);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageJPG::CxImageJPG(): CxImage(CXIMAGE_FORMAT_JPG)
|
||||||
|
{
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
m_exif = NULL;
|
||||||
|
memset(&info.ExifInfo, 0, sizeof(EXIFINFO));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageJPG::~CxImageJPG()
|
||||||
|
{
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
if (m_exif) delete m_exif;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
bool CxImageJPG::DecodeExif(CxFile * hFile)
|
||||||
|
{
|
||||||
|
m_exif = new CxExifInfo(&info.ExifInfo);
|
||||||
|
if (m_exif){
|
||||||
|
int32_t pos=hFile->Tell();
|
||||||
|
m_exif->DecodeExif(hFile);
|
||||||
|
hFile->Seek(pos,SEEK_SET);
|
||||||
|
return m_exif->m_exifinfo->IsExif;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJPG::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
|
||||||
|
{
|
||||||
|
CxIOFile file;
|
||||||
|
if (!file.Open(filename, _T("rb"))) return false;
|
||||||
|
CxExifInfo exif(&info.ExifInfo);
|
||||||
|
exif.DecodeExif(&file);
|
||||||
|
if (info.ExifInfo.IsExif && info.ExifInfo.ThumbnailPointer && info.ExifInfo.ThumbnailSize > 0)
|
||||||
|
{ // have a thumbnail - check whether it needs rotating or resizing
|
||||||
|
// TODO: Write a fast routine to read the jpeg header to get the width and height
|
||||||
|
CxImage image(info.ExifInfo.ThumbnailPointer, info.ExifInfo.ThumbnailSize, CXIMAGE_FORMAT_JPG);
|
||||||
|
if (image.IsValid())
|
||||||
|
{
|
||||||
|
if (image.GetWidth() > 256 || image.GetHeight() > 256)
|
||||||
|
{ // resize the image
|
||||||
|
// float amount = 256.0f / max(image.GetWidth(), image.GetHeight());
|
||||||
|
// image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0);
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
if (info.ExifInfo.Orientation != 1)
|
||||||
|
image.RotateExif(info.ExifInfo.Orientation);
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
return image.Save(outname, CXIMAGE_FORMAT_JPG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// nice and fast, but we can't resize :(
|
||||||
|
/*
|
||||||
|
FILE *hFileWrite;
|
||||||
|
if ((hFileWrite=fopen(outname, "wb")) != NULL)
|
||||||
|
{
|
||||||
|
fwrite(m_exifinfo.ThumbnailPointer, m_exifinfo.ThumbnailSize, 1, hFileWrite);
|
||||||
|
fclose(hFileWrite);
|
||||||
|
return true;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif //CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJPG::Decode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool is_exif = false;
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
is_exif = DecodeExif(hFile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CImageIterator iter(this);
|
||||||
|
/* This struct contains the JPEG decompression parameters and pointers to
|
||||||
|
* working space (which is allocated as needed by the JPEG library).
|
||||||
|
*/
|
||||||
|
struct jpeg_decompress_struct cinfo;
|
||||||
|
/* We use our private extension JPEG error handler. <CSC> */
|
||||||
|
struct jpg_error_mgr jerr;
|
||||||
|
jerr.buffer=info.szLastError;
|
||||||
|
/* More stuff */
|
||||||
|
JSAMPARRAY buffer; /* Output row buffer */
|
||||||
|
int32_t row_stride; /* physical row width in output buffer */
|
||||||
|
|
||||||
|
/* In this example we want to open the input file before doing anything else,
|
||||||
|
* so that the setjmp() error recovery below can assume the file is open.
|
||||||
|
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
||||||
|
* requires it in order to read binary files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Step 1: allocate and initialize JPEG decompression object */
|
||||||
|
/* We set up the normal JPEG error routines, then override error_exit. */
|
||||||
|
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||||
|
jerr.pub.error_exit = ima_jpeg_error_exit;
|
||||||
|
|
||||||
|
CxFileJpg src(hFile);
|
||||||
|
|
||||||
|
/* Establish the setjmp return context for my_error_exit to use. */
|
||||||
|
if (setjmp(jerr.setjmp_buffer)) {
|
||||||
|
/* If we get here, the JPEG code has signaled an error.
|
||||||
|
* We need to clean up the JPEG object, close the input file, and return.
|
||||||
|
*/
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Now we can initialize the JPEG decompression object. */
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
|
/* Step 2: specify data source (eg, a file) */
|
||||||
|
//jpeg_stdio_src(&cinfo, infile);
|
||||||
|
cinfo.src = &src;
|
||||||
|
|
||||||
|
/* Step 3: read file parameters with jpeg_read_header() */
|
||||||
|
(void) jpeg_read_header(&cinfo, TRUE);
|
||||||
|
|
||||||
|
/* Step 4 <chupeev> handle decoder options*/
|
||||||
|
uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114]
|
||||||
|
if ((dwCodecOptions & DECODE_GRAYSCALE) != 0)
|
||||||
|
cinfo.out_color_space = JCS_GRAYSCALE;
|
||||||
|
if ((dwCodecOptions & DECODE_QUANTIZE) != 0) {
|
||||||
|
cinfo.quantize_colors = TRUE;
|
||||||
|
cinfo.desired_number_of_colors = GetJpegQuality();
|
||||||
|
}
|
||||||
|
if ((dwCodecOptions & DECODE_DITHER) != 0)
|
||||||
|
cinfo.dither_mode = m_nDither;
|
||||||
|
if ((dwCodecOptions & DECODE_ONEPASS) != 0)
|
||||||
|
cinfo.two_pass_quantize = FALSE;
|
||||||
|
if ((dwCodecOptions & DECODE_NOSMOOTH) != 0)
|
||||||
|
cinfo.do_fancy_upsampling = FALSE;
|
||||||
|
|
||||||
|
//<DP>: Load true color images as RGB (no quantize)
|
||||||
|
/* Step 4: set parameters for decompression */
|
||||||
|
/* if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) {
|
||||||
|
* cinfo.quantize_colors = TRUE;
|
||||||
|
* cinfo.desired_number_of_colors = 128;
|
||||||
|
*}
|
||||||
|
*/ //</DP>
|
||||||
|
|
||||||
|
cinfo.scale_num = 1;
|
||||||
|
// Set the scale <ignacio>
|
||||||
|
cinfo.scale_denom = GetJpegScale();
|
||||||
|
|
||||||
|
// Borrowed the idea from GIF implementation <ignacio>
|
||||||
|
if (info.nEscape == -1) {
|
||||||
|
// Return output dimensions only
|
||||||
|
jpeg_calc_output_dimensions(&cinfo);
|
||||||
|
head.biWidth = cinfo.output_width;
|
||||||
|
head.biHeight = cinfo.output_height;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_JPG;
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 5: Start decompressor */
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
|
/* We may need to do some setup of our own at this point before reading
|
||||||
|
* the data. After jpeg_start_decompress() we have the correct scaled
|
||||||
|
* output image dimensions available, as well as the output colormap
|
||||||
|
* if we asked for color quantization.
|
||||||
|
*/
|
||||||
|
//Create the image using output dimensions <ignacio>
|
||||||
|
//Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
|
||||||
|
Create(cinfo.output_width, cinfo.output_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
|
||||||
|
|
||||||
|
if (!pDib) longjmp(jerr.setjmp_buffer, 1); //<DP> check if the image has been created
|
||||||
|
|
||||||
|
if (is_exif){
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
if ((info.ExifInfo.Xresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0))
|
||||||
|
SetXDPI((int32_t)(info.ExifInfo.Xresolution/info.ExifInfo.ResolutionUnit));
|
||||||
|
if ((info.ExifInfo.Yresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0))
|
||||||
|
SetYDPI((int32_t)(info.ExifInfo.Yresolution/info.ExifInfo.ResolutionUnit));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
switch (cinfo.density_unit) {
|
||||||
|
case 0: // [andy] fix for aspect ratio...
|
||||||
|
if((cinfo.Y_density > 0) && (cinfo.X_density > 0)){
|
||||||
|
SetYDPI((int32_t)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density))));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter
|
||||||
|
SetXDPI((int32_t)floor(cinfo.X_density * 2.54 + 0.5));
|
||||||
|
SetYDPI((int32_t)floor(cinfo.Y_density * 2.54 + 0.5));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetXDPI(cinfo.X_density);
|
||||||
|
SetYDPI(cinfo.Y_density);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cinfo.out_color_space==JCS_GRAYSCALE){
|
||||||
|
SetGrayPalette();
|
||||||
|
head.biClrUsed =256;
|
||||||
|
} else {
|
||||||
|
if (cinfo.quantize_colors){
|
||||||
|
SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]);
|
||||||
|
head.biClrUsed=cinfo.actual_number_of_colors;
|
||||||
|
} else {
|
||||||
|
head.biClrUsed=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* JSAMPLEs per row in output buffer */
|
||||||
|
row_stride = cinfo.output_width * cinfo.output_components;
|
||||||
|
|
||||||
|
/* Make a one-row-high sample array that will go away when done with image */
|
||||||
|
buffer = (*cinfo.mem->alloc_sarray)
|
||||||
|
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
|
||||||
|
|
||||||
|
/* Step 6: while (scan lines remain to be read) */
|
||||||
|
/* jpeg_read_scanlines(...); */
|
||||||
|
/* Here we use the library's state variable cinfo.output_scanline as the
|
||||||
|
* loop counter, so that we don't have to keep track ourselves.
|
||||||
|
*/
|
||||||
|
iter.Upset();
|
||||||
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
|
|
||||||
|
if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
|
||||||
|
// info.nProgress = (int32_t)(100*cinfo.output_scanline/cinfo.output_height);
|
||||||
|
//<DP> Step 6a: CMYK->RGB */
|
||||||
|
if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
|
||||||
|
uint8_t k,*dst,*src;
|
||||||
|
dst=iter.GetRow();
|
||||||
|
src=buffer[0];
|
||||||
|
for(int32_t x3=0,x4=0; x3<(int32_t)info.dwEffWidth && x4<row_stride; x3+=3, x4+=4){
|
||||||
|
k=src[x4+3];
|
||||||
|
dst[x3] =(uint8_t)((k * src[x4+2])/255);
|
||||||
|
dst[x3+1]=(uint8_t)((k * src[x4+1])/255);
|
||||||
|
dst[x3+2]=(uint8_t)((k * src[x4+0])/255);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Assume put_scanline_someplace wants a pointer and sample count. */
|
||||||
|
iter.SetRow(buffer[0], row_stride);
|
||||||
|
}
|
||||||
|
iter.PrevRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 7: Finish decompression */
|
||||||
|
(void) jpeg_finish_decompress(&cinfo);
|
||||||
|
/* We can ignore the return value since suspension is not possible
|
||||||
|
* with the stdio data source.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//<DP> Step 7A: Swap red and blue components
|
||||||
|
// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
|
||||||
|
if ((cinfo.num_components==3)&&(cinfo.quantize_colors==FALSE)){
|
||||||
|
uint8_t* r0=GetBits();
|
||||||
|
for(int32_t y=0;y<head.biHeight;y++){
|
||||||
|
if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
|
||||||
|
RGBtoBGR(r0,3*head.biWidth);
|
||||||
|
r0+=info.dwEffWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 8: Release JPEG decompression object */
|
||||||
|
/* This is an important step since it will release a good deal of memory. */
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
|
/* At this point you may want to check to see whether any corrupt-data
|
||||||
|
* warnings occurred (test whether jerr.pub.num_warnings is nonzero).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* And we're done! */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageJPG::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
if (head.biClrUsed!=0 && !IsGrayScale()){
|
||||||
|
strcpy(info.szLastError,"JPEG can save only RGB or GreyScale images");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// necessary for EXIF, and for roll backs
|
||||||
|
int32_t pos=hFile->Tell();
|
||||||
|
|
||||||
|
/* This struct contains the JPEG compression parameters and pointers to
|
||||||
|
* working space (which is allocated as needed by the JPEG library).
|
||||||
|
* It is possible to have several such structures, representing multiple
|
||||||
|
* compression/decompression processes, in existence at once. We refer
|
||||||
|
* to any one struct (and its associated working data) as a "JPEG object".
|
||||||
|
*/
|
||||||
|
struct jpeg_compress_struct cinfo;
|
||||||
|
/* This struct represents a JPEG error handler. It is declared separately
|
||||||
|
* because applications often want to supply a specialized error handler
|
||||||
|
* (see the second half of this file for an example). But here we just
|
||||||
|
* take the easy way out and use the standard error handler, which will
|
||||||
|
* print a message on stderr and call exit() if compression fails.
|
||||||
|
* Note that this struct must live as int32_t as the main JPEG parameter
|
||||||
|
* struct, to avoid dangling-pointer problems.
|
||||||
|
*/
|
||||||
|
//struct jpeg_error_mgr jerr;
|
||||||
|
/* We use our private extension JPEG error handler. <CSC> */
|
||||||
|
struct jpg_error_mgr jerr;
|
||||||
|
jerr.buffer=info.szLastError;
|
||||||
|
/* More stuff */
|
||||||
|
int32_t row_stride; /* physical row width in image buffer */
|
||||||
|
JSAMPARRAY buffer; /* Output row buffer */
|
||||||
|
|
||||||
|
/* Step 1: allocate and initialize JPEG compression object */
|
||||||
|
/* We have to set up the error handler first, in case the initialization
|
||||||
|
* step fails. (Unlikely, but it could happen if you are out of memory.)
|
||||||
|
* This routine fills in the contents of struct jerr, and returns jerr's
|
||||||
|
* address which we place into the link field in cinfo.
|
||||||
|
*/
|
||||||
|
//cinfo.err = jpeg_std_error(&jerr); <CSC>
|
||||||
|
/* We set up the normal JPEG error routines, then override error_exit. */
|
||||||
|
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||||
|
jerr.pub.error_exit = ima_jpeg_error_exit;
|
||||||
|
|
||||||
|
/* Establish the setjmp return context for my_error_exit to use. */
|
||||||
|
if (setjmp(jerr.setjmp_buffer)) {
|
||||||
|
/* If we get here, the JPEG code has signaled an error.
|
||||||
|
* We need to clean up the JPEG object, close the input file, and return.
|
||||||
|
*/
|
||||||
|
strcpy(info.szLastError, jerr.buffer); //<CSC>
|
||||||
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we can initialize the JPEG compression object. */
|
||||||
|
jpeg_create_compress(&cinfo);
|
||||||
|
/* Step 2: specify data destination (eg, a file) */
|
||||||
|
/* Note: steps 2 and 3 can be done in either order. */
|
||||||
|
/* Here we use the library-supplied code to send compressed data to a
|
||||||
|
* stdio stream. You can also write your own code to do something else.
|
||||||
|
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
||||||
|
* requires it in order to write binary files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//jpeg_stdio_dest(&cinfo, outfile);
|
||||||
|
CxFileJpg dest(hFile);
|
||||||
|
cinfo.dest = &dest;
|
||||||
|
|
||||||
|
/* Step 3: set parameters for compression */
|
||||||
|
/* First we supply a description of the input image.
|
||||||
|
* Four fields of the cinfo struct must be filled in:
|
||||||
|
*/
|
||||||
|
cinfo.image_width = GetWidth(); // image width and height, in pixels
|
||||||
|
cinfo.image_height = GetHeight();
|
||||||
|
|
||||||
|
if (IsGrayScale()){
|
||||||
|
cinfo.input_components = 1; // # of color components per pixel
|
||||||
|
cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
|
||||||
|
} else {
|
||||||
|
cinfo.input_components = 3; // # of color components per pixel
|
||||||
|
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now use the library's routine to set default compression parameters.
|
||||||
|
* (You must set at least cinfo.in_color_space before calling this,
|
||||||
|
* since the defaults depend on the source color space.)
|
||||||
|
*/
|
||||||
|
jpeg_set_defaults(&cinfo);
|
||||||
|
/* Now you can set any non-default parameters you wish to.
|
||||||
|
* Here we just illustrate the use of quality (quantization table) scaling:
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114]
|
||||||
|
//#ifdef C_ARITH_CODING_SUPPORTED
|
||||||
|
if ((dwCodecOptions & ENCODE_ARITHMETIC) != 0)
|
||||||
|
cinfo.arith_code = TRUE;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#ifdef ENTROPY_OPT_SUPPORTED
|
||||||
|
if ((dwCodecOptions & ENCODE_OPTIMIZE) != 0)
|
||||||
|
cinfo.optimize_coding = TRUE;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
if ((dwCodecOptions & ENCODE_GRAYSCALE) != 0)
|
||||||
|
jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
|
||||||
|
|
||||||
|
if ((dwCodecOptions & ENCODE_SMOOTHING) != 0)
|
||||||
|
cinfo.smoothing_factor = m_nSmoothing;
|
||||||
|
|
||||||
|
jpeg_set_quality(&cinfo, GetJpegQuality(), (dwCodecOptions & ENCODE_BASELINE) != 0);
|
||||||
|
|
||||||
|
//#ifdef C_PROGRESSIVE_SUPPORTED
|
||||||
|
if ((dwCodecOptions & ENCODE_PROGRESSIVE) != 0)
|
||||||
|
jpeg_simple_progression(&cinfo);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifdef C_LOSSLESS_SUPPORTED
|
||||||
|
if ((dwCodecOptions & ENCODE_LOSSLESS) != 0)
|
||||||
|
jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//SetCodecOption(ENCODE_SUBSAMPLE_444 | GetCodecOption(CXIMAGE_FORMAT_JPG),CXIMAGE_FORMAT_JPG);
|
||||||
|
|
||||||
|
// 2x2, 1x1, 1x1 (4:1:1) : High (default sub sampling)
|
||||||
|
cinfo.comp_info[0].h_samp_factor = 2;
|
||||||
|
cinfo.comp_info[0].v_samp_factor = 2;
|
||||||
|
cinfo.comp_info[1].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[1].v_samp_factor = 1;
|
||||||
|
cinfo.comp_info[2].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[2].v_samp_factor = 1;
|
||||||
|
|
||||||
|
if ((dwCodecOptions & ENCODE_SUBSAMPLE_422) != 0){
|
||||||
|
// 2x1, 1x1, 1x1 (4:2:2) : Medium
|
||||||
|
cinfo.comp_info[0].h_samp_factor = 2;
|
||||||
|
cinfo.comp_info[0].v_samp_factor = 1;
|
||||||
|
cinfo.comp_info[1].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[1].v_samp_factor = 1;
|
||||||
|
cinfo.comp_info[2].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[2].v_samp_factor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dwCodecOptions & ENCODE_SUBSAMPLE_444) != 0){
|
||||||
|
// 1x1 1x1 1x1 (4:4:4) : None
|
||||||
|
cinfo.comp_info[0].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[0].v_samp_factor = 1;
|
||||||
|
cinfo.comp_info[1].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[1].v_samp_factor = 1;
|
||||||
|
cinfo.comp_info[2].h_samp_factor = 1;
|
||||||
|
cinfo.comp_info[2].v_samp_factor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cinfo.density_unit=1;
|
||||||
|
cinfo.X_density=(uint16_t)GetXDPI();
|
||||||
|
cinfo.Y_density=(uint16_t)GetYDPI();
|
||||||
|
|
||||||
|
/* Step 4: Start compressor */
|
||||||
|
/* TRUE ensures that we will write a complete interchange-JPEG file.
|
||||||
|
* Pass TRUE unless you are very sure of what you're doing.
|
||||||
|
*/
|
||||||
|
jpeg_start_compress(&cinfo, TRUE);
|
||||||
|
|
||||||
|
/* Step 5: while (scan lines remain to be written) */
|
||||||
|
/* jpeg_write_scanlines(...); */
|
||||||
|
/* Here we use the library's state variable cinfo.next_scanline as the
|
||||||
|
* loop counter, so that we don't have to keep track ourselves.
|
||||||
|
* To keep things simple, we pass one scanline per call; you can pass
|
||||||
|
* more if you wish, though.
|
||||||
|
*/
|
||||||
|
row_stride = info.dwEffWidth; /* JSAMPLEs per row in image_buffer */
|
||||||
|
|
||||||
|
//<DP> "8+row_stride" fix heap deallocation problem during debug???
|
||||||
|
buffer = (*cinfo.mem->alloc_sarray)
|
||||||
|
((j_common_ptr) &cinfo, JPOOL_IMAGE, 8+row_stride, 1);
|
||||||
|
|
||||||
|
CImageIterator iter(this);
|
||||||
|
|
||||||
|
iter.Upset();
|
||||||
|
while (cinfo.next_scanline < cinfo.image_height) {
|
||||||
|
// info.nProgress = (int32_t)(100*cinfo.next_scanline/cinfo.image_height);
|
||||||
|
iter.GetRow(buffer[0], row_stride);
|
||||||
|
// not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
|
||||||
|
if (head.biClrUsed==0){ // swap R & B for RGB images
|
||||||
|
RGBtoBGR(buffer[0], row_stride); // Lance : 1998/09/01 : Bug ID: EXP-2.1.1-9
|
||||||
|
}
|
||||||
|
iter.PrevRow();
|
||||||
|
(void) jpeg_write_scanlines(&cinfo, buffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 6: Finish compression */
|
||||||
|
jpeg_finish_compress(&cinfo);
|
||||||
|
|
||||||
|
/* Step 7: release JPEG compression object */
|
||||||
|
/* This is an important step since it will release a good deal of memory. */
|
||||||
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
|
||||||
|
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
if (m_exif && m_exif->m_exifinfo->IsExif){
|
||||||
|
// discard useless sections (if any) read from original image
|
||||||
|
m_exif->DiscardAllButExif();
|
||||||
|
// read new created image, to split the sections
|
||||||
|
hFile->Seek(pos,SEEK_SET);
|
||||||
|
m_exif->DecodeExif(hFile,EXIF_READ_IMAGE);
|
||||||
|
// save back the image, adding EXIF section
|
||||||
|
hFile->Seek(pos,SEEK_SET);
|
||||||
|
m_exif->EncodeExif(hFile);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* And we're done! */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_JPG
|
||||||
|
|
||||||
283
Raw2Bmp_MFC/include/ximajpg.h
Normal file
283
Raw2Bmp_MFC/include/ximajpg.h
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
* File: ximajpg.h
|
||||||
|
* Purpose: JPG Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
|
||||||
|
*
|
||||||
|
* Special thanks to Chris Shearer Cooper for CxFileJpg tips & code
|
||||||
|
*
|
||||||
|
* EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
|
||||||
|
*
|
||||||
|
* original CImageJPG and CImageIterator implementation are:
|
||||||
|
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
|
||||||
|
*
|
||||||
|
* This software is based in part on the work of the Independent JPEG Group.
|
||||||
|
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaJPEG_h)
|
||||||
|
#define __ximaJPEG_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_JPG
|
||||||
|
|
||||||
|
#define CXIMAGEJPG_SUPPORT_EXIF CXIMAGE_SUPPORT_EXIF
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#ifdef _LINUX
|
||||||
|
#include <jpeglib.h>
|
||||||
|
#include <jerror.h>
|
||||||
|
#else
|
||||||
|
#include "../jpeg/jpeglib.h"
|
||||||
|
#include "../jpeg/jerror.h"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class DLL_EXP CxImageJPG: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImageJPG();
|
||||||
|
~CxImageJPG();
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// JPEG markers consist of one or more 0xFF bytes, followed by a marker
|
||||||
|
// code byte (which is not an FF). Here are the marker codes of interest
|
||||||
|
// in this program. (See jdmarker.c for a more complete list.)
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define M_SOF0 0xC0 // Start Of Frame N
|
||||||
|
#define M_SOF1 0xC1 // N indicates which compression process
|
||||||
|
#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use
|
||||||
|
#define M_SOF3 0xC3
|
||||||
|
#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers
|
||||||
|
#define M_SOF6 0xC6
|
||||||
|
#define M_SOF7 0xC7
|
||||||
|
#define M_SOF9 0xC9
|
||||||
|
#define M_SOF10 0xCA
|
||||||
|
#define M_SOF11 0xCB
|
||||||
|
#define M_SOF13 0xCD
|
||||||
|
#define M_SOF14 0xCE
|
||||||
|
#define M_SOF15 0xCF
|
||||||
|
#define M_SOI 0xD8 // Start Of Image (beginning of datastream)
|
||||||
|
#define M_EOI 0xD9 // End Of Image (end of datastream)
|
||||||
|
#define M_SOS 0xDA // Start Of Scan (begins compressed data)
|
||||||
|
#define M_JFIF 0xE0 // Jfif marker
|
||||||
|
#define M_EXIF 0xE1 // Exif marker
|
||||||
|
#define M_COM 0xFE // COMment
|
||||||
|
|
||||||
|
#define PSEUDO_IMAGE_MARKER 0x123; // Extra value.
|
||||||
|
|
||||||
|
#define EXIF_READ_EXIF 0x01
|
||||||
|
#define EXIF_READ_IMAGE 0x02
|
||||||
|
#define EXIF_READ_ALL 0x03
|
||||||
|
|
||||||
|
class DLL_EXP CxExifInfo
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef struct tag_Section_t{
|
||||||
|
uint8_t* Data;
|
||||||
|
int32_t Type;
|
||||||
|
unsigned Size;
|
||||||
|
} Section_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
EXIFINFO* m_exifinfo;
|
||||||
|
char m_szLastError[256];
|
||||||
|
CxExifInfo(EXIFINFO* info = NULL);
|
||||||
|
~CxExifInfo();
|
||||||
|
bool DecodeExif(CxFile * hFile, int32_t nReadMode = EXIF_READ_EXIF);
|
||||||
|
bool EncodeExif(CxFile * hFile);
|
||||||
|
void DiscardAllButExif();
|
||||||
|
protected:
|
||||||
|
bool process_EXIF(uint8_t * CharBuf, uint32_t length);
|
||||||
|
void process_COM (const uint8_t * Data, int32_t length);
|
||||||
|
void process_SOFn (const uint8_t * Data, int32_t marker);
|
||||||
|
int32_t Get16u(void * Short);
|
||||||
|
int32_t Get16m(void * Short);
|
||||||
|
int32_t Get32s(void * Long);
|
||||||
|
uint32_t Get32u(void * Long);
|
||||||
|
double ConvertAnyFormat(void * ValuePtr, int32_t Format);
|
||||||
|
void* FindSection(int32_t SectionType);
|
||||||
|
bool ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength,
|
||||||
|
EXIFINFO * const pInfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel=0);
|
||||||
|
int32_t ExifImageWidth;
|
||||||
|
int32_t MotorolaOrder;
|
||||||
|
Section_t Sections[MAX_SECTIONS];
|
||||||
|
int32_t SectionsRead;
|
||||||
|
bool freeinfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
CxExifInfo* m_exif;
|
||||||
|
bool DecodeExif(CxFile * hFile);
|
||||||
|
bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); }
|
||||||
|
bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type);
|
||||||
|
|
||||||
|
#endif //CXIMAGEJPG_SUPPORT_EXIF
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////// C x F i l e J p g ////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// thanks to Chris Shearer Cooper <cscooper(at)frii(dot)com>
|
||||||
|
class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { eBufSize = 4096 };
|
||||||
|
|
||||||
|
CxFileJpg(CxFile* pFile)
|
||||||
|
{
|
||||||
|
m_pFile = pFile;
|
||||||
|
|
||||||
|
init_destination = InitDestination;
|
||||||
|
empty_output_buffer = EmptyOutputBuffer;
|
||||||
|
term_destination = TermDestination;
|
||||||
|
|
||||||
|
init_source = InitSource;
|
||||||
|
fill_input_buffer = FillInputBuffer;
|
||||||
|
skip_input_data = SkipInputData;
|
||||||
|
resync_to_restart = jpeg_resync_to_restart; // use default method
|
||||||
|
term_source = TermSource;
|
||||||
|
next_input_byte = NULL; //* => next byte to read from buffer
|
||||||
|
bytes_in_buffer = 0; //* # of bytes remaining in buffer
|
||||||
|
|
||||||
|
m_pBuffer = new uint8_t[eBufSize];
|
||||||
|
}
|
||||||
|
~CxFileJpg()
|
||||||
|
{
|
||||||
|
delete [] m_pBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitDestination(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
|
||||||
|
pDest->next_output_byte = pDest->m_pBuffer;
|
||||||
|
pDest->free_in_buffer = eBufSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean EmptyOutputBuffer(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
|
||||||
|
if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize)
|
||||||
|
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||||
|
pDest->next_output_byte = pDest->m_pBuffer;
|
||||||
|
pDest->free_in_buffer = eBufSize;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TermDestination(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
|
||||||
|
size_t datacount = eBufSize - pDest->free_in_buffer;
|
||||||
|
/* Write any data remaining in the buffer */
|
||||||
|
if (datacount > 0) {
|
||||||
|
if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount))
|
||||||
|
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||||
|
}
|
||||||
|
pDest->m_pFile->Flush();
|
||||||
|
/* Make sure we wrote the output file OK */
|
||||||
|
if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitSource(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
|
||||||
|
pSource->m_bStartOfFile = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean FillInputBuffer(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
size_t nbytes;
|
||||||
|
CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
|
||||||
|
nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize);
|
||||||
|
if (nbytes <= 0){
|
||||||
|
if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error
|
||||||
|
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||||
|
WARNMS(cinfo, JWRN_JPEG_EOF);
|
||||||
|
// Insert a fake EOI marker
|
||||||
|
pSource->m_pBuffer[0] = (JOCTET) 0xFF;
|
||||||
|
pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI;
|
||||||
|
nbytes = 2;
|
||||||
|
}
|
||||||
|
pSource->next_input_byte = pSource->m_pBuffer;
|
||||||
|
pSource->bytes_in_buffer = nbytes;
|
||||||
|
pSource->m_bStartOfFile = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SkipInputData(j_decompress_ptr cinfo, long num_bytes)
|
||||||
|
{
|
||||||
|
CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
|
||||||
|
if (num_bytes > 0){
|
||||||
|
while (num_bytes > (int32_t)pSource->bytes_in_buffer){
|
||||||
|
num_bytes -= (int32_t)pSource->bytes_in_buffer;
|
||||||
|
FillInputBuffer(cinfo);
|
||||||
|
// note we assume that fill_input_buffer will never return FALSE,
|
||||||
|
// so suspension need not be handled.
|
||||||
|
}
|
||||||
|
pSource->next_input_byte += (size_t) num_bytes;
|
||||||
|
pSource->bytes_in_buffer -= (size_t) num_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TermSource(j_decompress_ptr /*cinfo*/)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
CxFile *m_pFile;
|
||||||
|
uint8_t *m_pBuffer;
|
||||||
|
bool m_bStartOfFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum CODEC_OPTION
|
||||||
|
{
|
||||||
|
ENCODE_BASELINE = 0x1,
|
||||||
|
ENCODE_ARITHMETIC = 0x2,
|
||||||
|
ENCODE_GRAYSCALE = 0x4,
|
||||||
|
ENCODE_OPTIMIZE = 0x8,
|
||||||
|
ENCODE_PROGRESSIVE = 0x10,
|
||||||
|
ENCODE_LOSSLESS = 0x20,
|
||||||
|
ENCODE_SMOOTHING = 0x40,
|
||||||
|
DECODE_GRAYSCALE = 0x80,
|
||||||
|
DECODE_QUANTIZE = 0x100,
|
||||||
|
DECODE_DITHER = 0x200,
|
||||||
|
DECODE_ONEPASS = 0x400,
|
||||||
|
DECODE_NOSMOOTH = 0x800,
|
||||||
|
ENCODE_SUBSAMPLE_422 = 0x1000,
|
||||||
|
ENCODE_SUBSAMPLE_444 = 0x2000
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t m_nPredictor;
|
||||||
|
int32_t m_nPointTransform;
|
||||||
|
int32_t m_nSmoothing;
|
||||||
|
int32_t m_nQuantize;
|
||||||
|
J_DITHER_MODE m_nDither;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
367
Raw2Bmp_MFC/include/ximalpha.cpp
Normal file
367
Raw2Bmp_MFC/include/ximalpha.cpp
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
// xImalpha.cpp : Alpha channel functions
|
||||||
|
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa AlphaSetMax
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::AlphaGetMax() const
|
||||||
|
{
|
||||||
|
return info.nAlphaMax;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets global Alpha (opacity) value applied to the whole image,
|
||||||
|
* valid only for painting functions.
|
||||||
|
* \param nAlphaMax: can be from 0 to 255
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaSetMax(uint8_t nAlphaMax)
|
||||||
|
{
|
||||||
|
info.nAlphaMax=nAlphaMax;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the image has a valid alpha channel.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaIsValid()
|
||||||
|
{
|
||||||
|
return pAlpha!=0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Enables the alpha palette, so the Draw() function changes its behavior.
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaPaletteEnable(bool enable)
|
||||||
|
{
|
||||||
|
info.bAlphaPaletteEnabled=enable;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* True if the alpha palette is enabled for painting.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaPaletteIsEnabled()
|
||||||
|
{
|
||||||
|
return info.bAlphaPaletteEnabled;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the alpha channel to full transparent. AlphaSet(0) has the same effect
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaClear()
|
||||||
|
{
|
||||||
|
if (pAlpha) memset(pAlpha,0,head.biWidth * head.biHeight);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the alpha level for the whole image.
|
||||||
|
* \param level : from 0 (transparent) to 255 (opaque)
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaSet(uint8_t level)
|
||||||
|
{
|
||||||
|
if (pAlpha) memset(pAlpha,level,head.biWidth * head.biHeight);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Allocates an empty (opaque) alpha channel.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaCreate()
|
||||||
|
{
|
||||||
|
if (pAlpha==NULL) {
|
||||||
|
pAlpha = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
if (pAlpha) memset(pAlpha,255,head.biWidth * head.biHeight);
|
||||||
|
}
|
||||||
|
return (pAlpha!=0);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::AlphaDelete()
|
||||||
|
{
|
||||||
|
if (pAlpha) { free(pAlpha); pAlpha=0; }
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::AlphaInvert()
|
||||||
|
{
|
||||||
|
if (pAlpha) {
|
||||||
|
uint8_t *iSrc=pAlpha;
|
||||||
|
int32_t n=head.biHeight*head.biWidth;
|
||||||
|
for(int32_t i=0; i < n; i++){
|
||||||
|
*iSrc=(uint8_t)~(*(iSrc));
|
||||||
|
iSrc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Imports an existing alpa channel from another image with the same width and height.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaCopy(CxImage &from)
|
||||||
|
{
|
||||||
|
if (from.pAlpha == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
|
||||||
|
if (pAlpha==NULL) pAlpha = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
if (pAlpha==NULL) return false;
|
||||||
|
memcpy(pAlpha,from.pAlpha,head.biWidth * head.biHeight);
|
||||||
|
info.nAlphaMax=from.info.nAlphaMax;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Creates the alpha channel from a gray scale image.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaSet(CxImage &from)
|
||||||
|
{
|
||||||
|
if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
|
||||||
|
if (pAlpha==NULL) pAlpha = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
uint8_t* src = from.info.pImage;
|
||||||
|
uint8_t* dst = pAlpha;
|
||||||
|
if (src==NULL || dst==NULL) return false;
|
||||||
|
for (int32_t y=0; y<head.biHeight; y++){
|
||||||
|
memcpy(dst,src,head.biWidth);
|
||||||
|
dst += head.biWidth;
|
||||||
|
src += from.info.dwEffWidth;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the alpha level for a single pixel
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaSet(const int32_t x,const int32_t y,const uint8_t level)
|
||||||
|
{
|
||||||
|
if (pAlpha && IsInside(x,y)) pAlpha[x+y*head.biWidth]=level;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Gets the alpha level for a single pixel
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::AlphaGet(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
if (pAlpha && IsInside(x,y)) return pAlpha[x+y*head.biWidth];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns pointer to alpha data for pixel (x,y).
|
||||||
|
*
|
||||||
|
* \author ***bd*** 2.2004
|
||||||
|
*/
|
||||||
|
uint8_t* CxImage::AlphaGetPointer(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
if (pAlpha && IsInside(x,y)) return pAlpha+x+y*head.biWidth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Get alpha value without boundscheck (a bit faster). Pixel must be inside the image.
|
||||||
|
*
|
||||||
|
* \author ***bd*** 2.2004
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::BlindAlphaGet(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (!IsInside(x,y) || (pAlpha==0))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return pAlpha[x+y*head.biWidth];
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Resets the alpha palette
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaPaletteClear()
|
||||||
|
{
|
||||||
|
RGBQUAD c;
|
||||||
|
for(uint16_t ip=0; ip<head.biClrUsed;ip++){
|
||||||
|
c=GetPaletteColor((uint8_t)ip);
|
||||||
|
c.rgbReserved=0;
|
||||||
|
SetPaletteColor((uint8_t)ip,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the image has a valid alpha palette.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaPaletteIsValid()
|
||||||
|
{
|
||||||
|
RGBQUAD c;
|
||||||
|
for(uint16_t ip=0; ip<head.biClrUsed;ip++){
|
||||||
|
c=GetPaletteColor((uint8_t)ip);
|
||||||
|
if (c.rgbReserved != 0) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
|
||||||
|
* The background color can be selected using SetTransColor().
|
||||||
|
*/
|
||||||
|
void CxImage::AlphaStrip()
|
||||||
|
{
|
||||||
|
bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
|
||||||
|
bool bAlphaIsValid = AlphaIsValid();
|
||||||
|
if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
|
||||||
|
RGBQUAD c;
|
||||||
|
int32_t a, a1;
|
||||||
|
if (head.biBitCount==24){
|
||||||
|
for(int32_t y=0; y<head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x<head.biWidth; x++){
|
||||||
|
c = BlindGetPixelColor(x,y);
|
||||||
|
if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
|
||||||
|
a1 = 256-a;
|
||||||
|
c.rgbBlue = (uint8_t)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
|
||||||
|
c.rgbGreen = (uint8_t)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
|
||||||
|
c.rgbRed = (uint8_t)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
|
||||||
|
BlindSetPixelColor(x,y,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AlphaDelete();
|
||||||
|
} else {
|
||||||
|
CxImage tmp(head.biWidth,head.biHeight,24);
|
||||||
|
if (!tmp.IsValid()){
|
||||||
|
strcpy(info.szLastError,tmp.GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t y=0; y<head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x<head.biWidth; x++){
|
||||||
|
c = BlindGetPixelColor(x,y);
|
||||||
|
if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
|
||||||
|
if (bAlphaPaletteIsValid) a=(c.rgbReserved*a)/255;
|
||||||
|
a1 = 256-a;
|
||||||
|
c.rgbBlue = (uint8_t)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
|
||||||
|
c.rgbGreen = (uint8_t)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
|
||||||
|
c.rgbRed = (uint8_t)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
|
||||||
|
tmp.BlindSetPixelColor(x,y,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Transfer(tmp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::AlphaFlip()
|
||||||
|
{
|
||||||
|
if (!pAlpha) return false;
|
||||||
|
|
||||||
|
uint8_t *buff = (uint8_t*)malloc(head.biWidth);
|
||||||
|
if (!buff) return false;
|
||||||
|
|
||||||
|
uint8_t *iSrc,*iDst;
|
||||||
|
iSrc = pAlpha + (head.biHeight-1)*head.biWidth;
|
||||||
|
iDst = pAlpha;
|
||||||
|
for (int32_t i=0; i<(head.biHeight/2); ++i)
|
||||||
|
{
|
||||||
|
memcpy(buff, iSrc, head.biWidth);
|
||||||
|
memcpy(iSrc, iDst, head.biWidth);
|
||||||
|
memcpy(iDst, buff, head.biWidth);
|
||||||
|
iSrc-=head.biWidth;
|
||||||
|
iDst+=head.biWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buff);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::AlphaMirror()
|
||||||
|
{
|
||||||
|
if (!pAlpha) return false;
|
||||||
|
uint8_t* pAlpha2 = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
if (!pAlpha2) return false;
|
||||||
|
uint8_t *iSrc,*iDst;
|
||||||
|
int32_t wdt=head.biWidth-1;
|
||||||
|
iSrc=pAlpha + wdt;
|
||||||
|
iDst=pAlpha2;
|
||||||
|
for(int32_t y=0; y < head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x <= wdt; x++)
|
||||||
|
*(iDst+x)=*(iSrc-x);
|
||||||
|
iSrc+=head.biWidth;
|
||||||
|
iDst+=head.biWidth;
|
||||||
|
}
|
||||||
|
free(pAlpha);
|
||||||
|
pAlpha=pAlpha2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Exports the alpha channel in a 8bpp grayscale image.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaSplit(CxImage *dest)
|
||||||
|
{
|
||||||
|
if (!pAlpha || !dest) return false;
|
||||||
|
|
||||||
|
CxImage tmp(head.biWidth,head.biHeight,8);
|
||||||
|
if (!tmp.IsValid()){
|
||||||
|
strcpy(info.szLastError,tmp.GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* src = pAlpha;
|
||||||
|
uint8_t* dst = tmp.info.pImage;
|
||||||
|
for (int32_t y=0; y<head.biHeight; y++){
|
||||||
|
memcpy(dst,src,head.biWidth);
|
||||||
|
dst += tmp.info.dwEffWidth;
|
||||||
|
src += head.biWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.SetGrayPalette();
|
||||||
|
dest->Transfer(tmp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Exports the alpha palette channel in a 8bpp grayscale image.
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaPaletteSplit(CxImage *dest)
|
||||||
|
{
|
||||||
|
if (!AlphaPaletteIsValid() || !dest) return false;
|
||||||
|
|
||||||
|
CxImage tmp(head.biWidth,head.biHeight,8);
|
||||||
|
if (!tmp.IsValid()){
|
||||||
|
strcpy(info.szLastError,tmp.GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t y=0; y<head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x<head.biWidth; x++){
|
||||||
|
tmp.BlindSetPixelIndex(x,y,BlindGetPixelColor(x,y).rgbReserved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.SetGrayPalette();
|
||||||
|
dest->Transfer(tmp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Merge in the alpha layer the transparent color mask
|
||||||
|
* (previously set with SetTransColor or SetTransIndex)
|
||||||
|
*/
|
||||||
|
bool CxImage::AlphaFromTransparency()
|
||||||
|
{
|
||||||
|
if (!IsValid() || !IsTransparent())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AlphaCreate();
|
||||||
|
|
||||||
|
for(int32_t y=0; y<head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x<head.biWidth; x++){
|
||||||
|
if (IsTransparent(x,y)){
|
||||||
|
AlphaSet(x,y,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
116
Raw2Bmp_MFC/include/ximalyr.cpp
Normal file
116
Raw2Bmp_MFC/include/ximalyr.cpp
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
// xImaLyr.cpp : Layers functions
|
||||||
|
/* 21/04/2003 v1.00 - Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_LAYERS
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* If the object is an internal layer, GetParent return its parent in the hierarchy.
|
||||||
|
*/
|
||||||
|
CxImage* CxImage::GetParent() const
|
||||||
|
{
|
||||||
|
return info.pParent;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Number of layers allocated directly by the object.
|
||||||
|
*/
|
||||||
|
int32_t CxImage::GetNumLayers() const
|
||||||
|
{
|
||||||
|
return info.nNumLayers;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Creates an empty layer. If position is less than 0, the new layer will be placed in the last position
|
||||||
|
*/
|
||||||
|
bool CxImage::LayerCreate(int32_t position)
|
||||||
|
{
|
||||||
|
if ( position < 0 || position > info.nNumLayers ) position = info.nNumLayers;
|
||||||
|
|
||||||
|
CxImage** ptmp = new CxImage*[info.nNumLayers + 1];
|
||||||
|
if (ptmp==0) return false;
|
||||||
|
|
||||||
|
int32_t i=0;
|
||||||
|
for (int32_t n=0; n<info.nNumLayers; n++){
|
||||||
|
if (position == n){
|
||||||
|
ptmp[n] = new CxImage();
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
ptmp[n+i]=ppLayers[n];
|
||||||
|
}
|
||||||
|
if (i==0) ptmp[info.nNumLayers] = new CxImage();
|
||||||
|
|
||||||
|
if (ptmp[position]){
|
||||||
|
ptmp[position]->info.pParent = this;
|
||||||
|
} else {
|
||||||
|
free(ptmp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.nNumLayers++;
|
||||||
|
delete [] ppLayers;
|
||||||
|
ppLayers = ptmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Deletes a layer. If position is less than 0, the last layer will be deleted
|
||||||
|
*/
|
||||||
|
bool CxImage::LayerDelete(int32_t position)
|
||||||
|
{
|
||||||
|
if ( position >= info.nNumLayers ) return false;
|
||||||
|
if ( position < 0) position = info.nNumLayers - 1;
|
||||||
|
if ( position < 0) return false;
|
||||||
|
|
||||||
|
if (info.nNumLayers>1){
|
||||||
|
|
||||||
|
CxImage** ptmp = new CxImage*[info.nNumLayers - 1];
|
||||||
|
if (ptmp==0) return false;
|
||||||
|
|
||||||
|
int32_t i=0;
|
||||||
|
for (int32_t n=0; n<info.nNumLayers; n++){
|
||||||
|
if (position == n){
|
||||||
|
delete ppLayers[n];
|
||||||
|
i=1;
|
||||||
|
}
|
||||||
|
ptmp[n]=ppLayers[n+i];
|
||||||
|
}
|
||||||
|
|
||||||
|
info.nNumLayers--;
|
||||||
|
delete [] ppLayers;
|
||||||
|
ppLayers = ptmp;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
delete ppLayers[0];
|
||||||
|
delete [] ppLayers;
|
||||||
|
ppLayers = 0;
|
||||||
|
info.nNumLayers = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::LayerDeleteAll()
|
||||||
|
{
|
||||||
|
if (ppLayers) {
|
||||||
|
for(int32_t n=0; n<info.nNumLayers;n++){ delete ppLayers[n]; }
|
||||||
|
delete [] ppLayers; ppLayers=0; info.nNumLayers = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns a pointer to a layer. If position is less than 0, the last layer will be returned
|
||||||
|
*/
|
||||||
|
CxImage* CxImage::GetLayer(int32_t position)
|
||||||
|
{
|
||||||
|
if ( ppLayers == NULL) return NULL;
|
||||||
|
if ( info.nNumLayers == 0) return NULL;
|
||||||
|
if ( position >= info.nNumLayers ) return NULL;
|
||||||
|
if ( position < 0) position = info.nNumLayers - 1;
|
||||||
|
return ppLayers[position];
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_LAYERS
|
||||||
430
Raw2Bmp_MFC/include/ximamng.cpp
Normal file
430
Raw2Bmp_MFC/include/ximamng.cpp
Normal file
@@ -0,0 +1,430 @@
|
|||||||
|
/*
|
||||||
|
* File: ximamng.cpp
|
||||||
|
* Purpose: Platform Independent MNG Image Class Loader and Writer
|
||||||
|
* Author: 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximamng.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// callbacks for the mng decoder:
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// memory allocation; data must be zeroed
|
||||||
|
static mng_ptr
|
||||||
|
mymngalloc( mng_size_t size )
|
||||||
|
{
|
||||||
|
return (mng_ptr)calloc(1, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// memory deallocation
|
||||||
|
static void mymngfree(mng_ptr p, mng_size_t size)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Stream open/close:
|
||||||
|
// since the user is responsible for opening and closing the file,
|
||||||
|
// we leave the default implementation open
|
||||||
|
static mng_bool mymngopenstream(mng_handle mng) { return MNG_TRUE; }
|
||||||
|
static mng_bool mymngopenstreamwrite(mng_handle mng) { return MNG_TRUE; }
|
||||||
|
static mng_bool mymngclosestream(mng_handle mng) { return MNG_TRUE; }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// feed data to the decoder
|
||||||
|
static mng_bool mymngreadstream(mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread)
|
||||||
|
{
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
// read the requested amount of data from the file
|
||||||
|
*bytesread = mymng->file->Read( buffer, sizeof(uint8_t), size);
|
||||||
|
return MNG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static mng_bool mymngwritestream (mng_handle mng, mng_ptr pBuf, mng_uint32 iSize, mng_uint32 *iWritten)
|
||||||
|
{
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
// write it
|
||||||
|
*iWritten = mymng->file->Write (pBuf, 1, iSize);
|
||||||
|
return MNG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// the header's been read. set up the display stuff
|
||||||
|
static mng_bool mymngprocessheader( mng_handle mng, mng_uint32 width, mng_uint32 height )
|
||||||
|
{
|
||||||
|
// normally the image buffer is allocated here,
|
||||||
|
// but in this module we don't know nothing about
|
||||||
|
// the final environment.
|
||||||
|
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
|
||||||
|
mymng->width = width;
|
||||||
|
mymng->height = height;
|
||||||
|
mymng->bpp = 24;
|
||||||
|
mymng->effwdt = ((((width * mymng->bpp) + 31) >> 5) << 2);
|
||||||
|
|
||||||
|
if (mng->bUseBKGD){
|
||||||
|
mymng->nBkgndIndex = 0;
|
||||||
|
mymng->nBkgndColor.rgbRed = mng->iBGred >> 8;
|
||||||
|
mymng->nBkgndColor.rgbGreen =mng->iBGgreen >> 8;
|
||||||
|
mymng->nBkgndColor.rgbBlue = mng->iBGblue >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
mymng->image = (uint8_t*)malloc(height * mymng->effwdt);
|
||||||
|
|
||||||
|
// tell the mng decoder about our bit-depth choice
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
mng_set_canvasstyle( mng, MNG_CANVAS_RGB8_A8 );
|
||||||
|
mymng->alpha = (uint8_t*)malloc(height * width);
|
||||||
|
#else
|
||||||
|
mng_set_canvasstyle( mng, MNG_CANVAS_BGR8);
|
||||||
|
mymng->alpha = NULL;
|
||||||
|
#endif
|
||||||
|
return MNG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// return a row pointer for the decoder to fill
|
||||||
|
static mng_ptr mymnggetcanvasline( mng_handle mng, mng_uint32 line )
|
||||||
|
{
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
return (mng_ptr)(mymng->image + (mymng->effwdt * (mymng->height - 1 - line)));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// return a row pointer for the decoder to fill for alpha channel
|
||||||
|
static mng_ptr mymnggetalphaline( mng_handle mng, mng_uint32 line )
|
||||||
|
{
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
return (mng_ptr)(mymng->alpha + (mymng->width * (mymng->height - 1 - line)));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// timer
|
||||||
|
static mng_uint32 mymnggetticks(mng_handle mng)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
return (mng_uint32)GetTickCount();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Refresh: actual frame need to be updated (Invalidate)
|
||||||
|
static mng_bool mymngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h)
|
||||||
|
{
|
||||||
|
// mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
return MNG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// interframe delay callback
|
||||||
|
static mng_bool mymngsettimer(mng_handle mng, mng_uint32 msecs)
|
||||||
|
{
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
|
||||||
|
mymng->delay = msecs; // set the timer for when the decoder wants to be woken
|
||||||
|
return MNG_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static mng_bool mymngerror(mng_handle mng, mng_int32 code, mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar text)
|
||||||
|
{
|
||||||
|
return mng_cleanup(&mng); //<Arkadiy Olovyannikov>
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CxImage members
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageMNG::CxImageMNG(): CxImage(CXIMAGE_FORMAT_MNG)
|
||||||
|
{
|
||||||
|
hmng = NULL;
|
||||||
|
memset(&mnginfo,0,sizeof(mngstuff));
|
||||||
|
mnginfo.nBkgndIndex = -1;
|
||||||
|
mnginfo.speed = 1.0f;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageMNG::~CxImageMNG()
|
||||||
|
{
|
||||||
|
// cleanup and return
|
||||||
|
if (mnginfo.thread){ //close the animation thread
|
||||||
|
mnginfo.animation_enabled=0;
|
||||||
|
ResumeThread(mnginfo.thread);
|
||||||
|
WaitForSingleObject(mnginfo.thread,500);
|
||||||
|
CloseHandle(mnginfo.thread);
|
||||||
|
}
|
||||||
|
// free objects
|
||||||
|
if (mnginfo.image) free(mnginfo.image);
|
||||||
|
if (mnginfo.alpha) free(mnginfo.alpha);
|
||||||
|
if (hmng) mng_cleanup(&hmng); //be sure it's not needed any more. (active timers ?)
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageMNG::SetCallbacks(mng_handle mng)
|
||||||
|
{
|
||||||
|
// set the callbacks
|
||||||
|
mng_setcb_errorproc(mng, mymngerror);
|
||||||
|
mng_setcb_openstream(mng, mymngopenstream);
|
||||||
|
mng_setcb_closestream(mng, mymngclosestream);
|
||||||
|
mng_setcb_readdata(mng, mymngreadstream);
|
||||||
|
mng_setcb_processheader(mng, mymngprocessheader);
|
||||||
|
mng_setcb_getcanvasline(mng, mymnggetcanvasline);
|
||||||
|
mng_setcb_refresh(mng, mymngrefresh);
|
||||||
|
mng_setcb_gettickcount(mng, mymnggetticks);
|
||||||
|
mng_setcb_settimer(mng, mymngsettimer);
|
||||||
|
mng_setcb_refresh(mng, mymngrefresh);
|
||||||
|
mng_setcb_getalphaline(mng, mymnggetalphaline);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// can't use the CxImage implementation because it looses mnginfo
|
||||||
|
bool CxImageMNG::Load(const TCHAR * imageFileName){
|
||||||
|
FILE* hFile; //file handle to read the image
|
||||||
|
#ifdef WIN32
|
||||||
|
if ((hFile=_tfopen(imageFileName,_T("rb")))==NULL) return false; // For UNICODE support
|
||||||
|
#else
|
||||||
|
if ((hFile=fopen(imageFileName,"rb"))==NULL) return false;
|
||||||
|
#endif
|
||||||
|
bool bOK = Decode(hFile);
|
||||||
|
fclose(hFile);
|
||||||
|
return bOK;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageMNG::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
// set up the mng decoder for our stream
|
||||||
|
hmng = mng_initialize(&mnginfo, (mng_memalloc)mymngalloc, (mng_memfree)mymngfree, MNG_NULL);
|
||||||
|
if (hmng == NULL) cx_throw("could not initialize libmng");
|
||||||
|
|
||||||
|
// set the file we want to play
|
||||||
|
mnginfo.file = hFile;
|
||||||
|
|
||||||
|
// Set the colorprofile, lcms uses this:
|
||||||
|
mng_set_srgb(hmng, MNG_TRUE );
|
||||||
|
// Set white as background color:
|
||||||
|
uint16_t Red,Green,Blue;
|
||||||
|
Red = Green = Blue = (255 << 8) + 255;
|
||||||
|
mng_set_bgcolor(hmng, Red, Green, Blue );
|
||||||
|
// If PNG Background is available, use it:
|
||||||
|
mng_set_usebkgd(hmng, MNG_TRUE );
|
||||||
|
|
||||||
|
// No need to store chunks:
|
||||||
|
mng_set_storechunks(hmng, MNG_FALSE);
|
||||||
|
// No need to wait: straight reading
|
||||||
|
mng_set_suspensionmode(hmng, MNG_FALSE);
|
||||||
|
|
||||||
|
SetCallbacks(hmng);
|
||||||
|
|
||||||
|
mng_datap pData = (mng_datap)hmng;
|
||||||
|
|
||||||
|
// read in the image
|
||||||
|
info.nNumFrames=0;
|
||||||
|
int32_t retval=MNG_NOERROR;
|
||||||
|
|
||||||
|
retval = mng_readdisplay(hmng);
|
||||||
|
|
||||||
|
if (retval != MNG_NOERROR && retval != MNG_NEEDTIMERWAIT){
|
||||||
|
mng_store_error(hmng,retval,0,0);
|
||||||
|
if (hmng->zErrortext){
|
||||||
|
cx_throw(hmng->zErrortext);
|
||||||
|
} else {
|
||||||
|
cx_throw("Error in MNG file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.nEscape == -1) {
|
||||||
|
// Return output dimensions only
|
||||||
|
head.biWidth = hmng->iWidth;
|
||||||
|
head.biHeight = hmng->iHeight;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_MNG;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read all
|
||||||
|
while(pData->bReading){
|
||||||
|
retval = mng_display_resume(hmng);
|
||||||
|
info.nNumFrames++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// single frame check:
|
||||||
|
if (retval != MNG_NEEDTIMERWAIT){
|
||||||
|
info.nNumFrames--;
|
||||||
|
} else {
|
||||||
|
mnginfo.animation=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.nNumFrames<=0) info.nNumFrames=1;
|
||||||
|
|
||||||
|
if (mnginfo.animation_enabled==0){
|
||||||
|
// select the frame
|
||||||
|
if (info.nFrame>=0 && info.nFrame<info.nNumFrames){
|
||||||
|
for (int32_t n=0;n<info.nFrame;n++) mng_display_resume(hmng);
|
||||||
|
} else cx_throw("Error: frame not present in MNG file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mnginfo.nBkgndIndex >= 0){
|
||||||
|
info.nBkgndIndex = mnginfo.nBkgndIndex;
|
||||||
|
info.nBkgndColor.rgbRed = mnginfo.nBkgndColor.rgbRed;
|
||||||
|
info.nBkgndColor.rgbGreen = mnginfo.nBkgndColor.rgbGreen;
|
||||||
|
info.nBkgndColor.rgbBlue = mnginfo.nBkgndColor.rgbBlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//store the newly created image
|
||||||
|
if (Create(mnginfo.width,mnginfo.height,mnginfo.bpp, CXIMAGE_FORMAT_MNG)){
|
||||||
|
memcpy(GetBits(), mnginfo.image, info.dwEffWidth * head.biHeight);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
SwapRGB2BGR();
|
||||||
|
AlphaCreate();
|
||||||
|
if(AlphaIsValid() && mnginfo.alpha){
|
||||||
|
memcpy(AlphaGetPointer(),mnginfo.alpha,mnginfo.width * mnginfo.height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else cx_throw("CxImageMNG::Decode cannot create image");
|
||||||
|
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageMNG::Encode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (head.biClrUsed != 0) cx_throw("MNG encoder can save only RGB images");
|
||||||
|
// set the file we want to play
|
||||||
|
mnginfo.file = hFile;
|
||||||
|
mnginfo.bpp = head.biBitCount;
|
||||||
|
mnginfo.effwdt = info.dwEffWidth;
|
||||||
|
mnginfo.height = head.biHeight;
|
||||||
|
mnginfo.width = head.biWidth;
|
||||||
|
|
||||||
|
mnginfo.image = (uint8_t*)malloc(head.biSizeImage);
|
||||||
|
if (mnginfo.image == NULL) cx_throw("could not allocate memory for MNG");
|
||||||
|
memcpy(mnginfo.image,info.pImage, head.biSizeImage);
|
||||||
|
|
||||||
|
// set up the mng decoder for our stream
|
||||||
|
hmng = mng_initialize(&mnginfo, (mng_memalloc)mymngalloc, (mng_memfree)mymngfree, MNG_NULL);
|
||||||
|
if (hmng == NULL) cx_throw("could not initialize libmng");
|
||||||
|
|
||||||
|
mng_setcb_openstream(hmng, mymngopenstreamwrite );
|
||||||
|
mng_setcb_closestream(hmng, mymngclosestream);
|
||||||
|
mng_setcb_writedata(hmng, mymngwritestream);
|
||||||
|
|
||||||
|
// Write File:
|
||||||
|
mng_create(hmng);
|
||||||
|
// Just a single Frame (save a normal PNG):
|
||||||
|
WritePNG(hmng, 0, 1 );
|
||||||
|
// Now write file:
|
||||||
|
mng_write(hmng);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Writes a single PNG datastream
|
||||||
|
void CxImageMNG::WritePNG( mng_handle hMNG, int32_t Frame, int32_t FrameCount )
|
||||||
|
{
|
||||||
|
mngstuff *mymng = (mngstuff *)mng_get_userdata(hMNG);
|
||||||
|
|
||||||
|
int32_t OffsetX=0,OffsetY=0,OffsetW=mymng->width,OffsetH=mymng->height;
|
||||||
|
|
||||||
|
uint8_t *tmpbuffer = new uint8_t[ (mymng->effwdt+1) * mymng->height];
|
||||||
|
if( tmpbuffer == 0 ) return;
|
||||||
|
|
||||||
|
// Write DEFI chunk.
|
||||||
|
mng_putchunk_defi( hMNG, 0, 0, 0, MNG_TRUE, OffsetX, OffsetY, MNG_FALSE, 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
// Write Header:
|
||||||
|
mng_putchunk_ihdr(
|
||||||
|
hMNG,
|
||||||
|
OffsetW, OffsetH,
|
||||||
|
MNG_BITDEPTH_8,
|
||||||
|
MNG_COLORTYPE_RGB,
|
||||||
|
MNG_COMPRESSION_DEFLATE,
|
||||||
|
MNG_FILTER_ADAPTIVE,
|
||||||
|
MNG_INTERLACE_NONE
|
||||||
|
);
|
||||||
|
|
||||||
|
// transfer data, add Filterbyte:
|
||||||
|
for( int32_t Row=0; Row<OffsetH; Row++ ){
|
||||||
|
// First Byte in each Scanline is Filterbyte: Currently 0 -> No Filter.
|
||||||
|
tmpbuffer[Row*(mymng->effwdt+1)]=0;
|
||||||
|
// Copy the scanline: (reverse order)
|
||||||
|
memcpy(tmpbuffer+Row*(mymng->effwdt+1)+1,
|
||||||
|
mymng->image+((OffsetH-1-(OffsetY+Row))*(mymng->effwdt))+OffsetX,mymng->effwdt);
|
||||||
|
// swap red and blue components
|
||||||
|
RGBtoBGR(tmpbuffer+Row*(mymng->effwdt+1)+1,mymng->effwdt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compress data with ZLib (Deflate):
|
||||||
|
uint8_t *dstbuffer = new uint8_t[(mymng->effwdt+1)*OffsetH];
|
||||||
|
if( dstbuffer == 0 ) return;
|
||||||
|
uint32_t dstbufferSize=(mymng->effwdt+1)*OffsetH;
|
||||||
|
|
||||||
|
// Compress data:
|
||||||
|
if(Z_OK != compress2((Bytef *)dstbuffer,(ULONG *)&dstbufferSize,(const Bytef*)tmpbuffer,
|
||||||
|
(ULONG) (mymng->effwdt+1)*OffsetH,9 )) return;
|
||||||
|
|
||||||
|
// Write Data into MNG File:
|
||||||
|
mng_putchunk_idat( hMNG, dstbufferSize, (mng_ptr*)dstbuffer);
|
||||||
|
mng_putchunk_iend(hMNG);
|
||||||
|
|
||||||
|
// Free the stuff:
|
||||||
|
delete [] tmpbuffer;
|
||||||
|
delete [] dstbuffer;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int32_t CxImageMNG::Resume()
|
||||||
|
{
|
||||||
|
if (MNG_NEEDTIMERWAIT == mng_display_resume(hmng)){
|
||||||
|
if (info.pImage==NULL){
|
||||||
|
Create(mnginfo.width,mnginfo.height,mnginfo.bpp, CXIMAGE_FORMAT_MNG);
|
||||||
|
}
|
||||||
|
if (IsValid()){
|
||||||
|
memcpy(GetBits(), mnginfo.image, info.dwEffWidth * head.biHeight);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
SwapRGB2BGR();
|
||||||
|
AlphaCreate();
|
||||||
|
if(AlphaIsValid() && mnginfo.alpha){
|
||||||
|
memcpy(AlphaGetPointer(),mnginfo.alpha,mnginfo.width * mnginfo.height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mnginfo.animation_enabled = 0;
|
||||||
|
}
|
||||||
|
return mnginfo.animation_enabled;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageMNG::SetSpeed(float speed)
|
||||||
|
{
|
||||||
|
if (speed>10.0) mnginfo.speed = 10.0f;
|
||||||
|
else if (speed<0.1) mnginfo.speed = 0.1f;
|
||||||
|
else mnginfo.speed=speed;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_MNG
|
||||||
88
Raw2Bmp_MFC/include/ximamng.h
Normal file
88
Raw2Bmp_MFC/include/ximamng.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* File: ximamng.h
|
||||||
|
* Purpose: Declaration of the MNG Image Class
|
||||||
|
* Author: Davide Pizzolato - www.xdp.it
|
||||||
|
* Created: 2001
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageMNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Special thanks to Frank Haug <f.haug(at)jdm(dot)de> for suggestions and code.
|
||||||
|
*
|
||||||
|
* original mng.cpp code created by Nikolaus Brennig, November 14th, 2000. <virtualnik(at)nol(dot)at>
|
||||||
|
*
|
||||||
|
* LIBMNG Copyright (c) 2000,2001 Gerard Juyn (gerard@libmng.com)
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__ximaMNG_h)
|
||||||
|
#define __ximaMNG_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_MNG
|
||||||
|
|
||||||
|
//#define MNG_NO_CMS
|
||||||
|
#define MNG_SUPPORT_DISPLAY
|
||||||
|
#define MNG_SUPPORT_READ
|
||||||
|
#define MNG_SUPPORT_WRITE
|
||||||
|
#define MNG_ACCESS_CHUNKS
|
||||||
|
#define MNG_STORE_CHUNKS
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "../mng/libmng.h"
|
||||||
|
#include "../mng/libmng_data.h"
|
||||||
|
#include "../mng/libmng_error.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
//uint32_t _stdcall RunMNGThread(void *lpParam);
|
||||||
|
|
||||||
|
typedef struct tagmngstuff
|
||||||
|
{
|
||||||
|
CxFile *file;
|
||||||
|
uint8_t *image;
|
||||||
|
uint8_t *alpha;
|
||||||
|
HANDLE thread;
|
||||||
|
mng_uint32 delay;
|
||||||
|
mng_uint32 width;
|
||||||
|
mng_uint32 height;
|
||||||
|
mng_uint32 effwdt;
|
||||||
|
mng_int16 bpp;
|
||||||
|
mng_bool animation;
|
||||||
|
mng_bool animation_enabled;
|
||||||
|
float speed;
|
||||||
|
int32_t nBkgndIndex;
|
||||||
|
RGBQUAD nBkgndColor;
|
||||||
|
} mngstuff;
|
||||||
|
|
||||||
|
class CxImageMNG: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImageMNG();
|
||||||
|
~CxImageMNG();
|
||||||
|
|
||||||
|
bool Load(const TCHAR * imageFileName);
|
||||||
|
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_MNG);}
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
int32_t Resume();
|
||||||
|
void SetSpeed(float speed);
|
||||||
|
|
||||||
|
mng_handle hmng;
|
||||||
|
mngstuff mnginfo;
|
||||||
|
protected:
|
||||||
|
void WritePNG(mng_handle hMNG, int32_t Frame, int32_t FrameCount );
|
||||||
|
void SetCallbacks(mng_handle mng);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
834
Raw2Bmp_MFC/include/ximapal.cpp
Normal file
834
Raw2Bmp_MFC/include/ximapal.cpp
Normal file
@@ -0,0 +1,834 @@
|
|||||||
|
// xImaPal.cpp : Palette and Pixel functions
|
||||||
|
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* returns the palette dimension in byte
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetPaletteSize()
|
||||||
|
{
|
||||||
|
return (head.biClrUsed * sizeof(RGBQUAD));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPaletteColor(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t alpha)
|
||||||
|
{
|
||||||
|
if ((pDib)&&(head.biClrUsed)){
|
||||||
|
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
|
||||||
|
if (idx<head.biClrUsed){
|
||||||
|
int32_t ldx=idx*sizeof(RGBQUAD);
|
||||||
|
iDst[ldx++] = (uint8_t) b;
|
||||||
|
iDst[ldx++] = (uint8_t) g;
|
||||||
|
iDst[ldx++] = (uint8_t) r;
|
||||||
|
iDst[ldx] = (uint8_t) alpha;
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPaletteColor(uint8_t idx, RGBQUAD c)
|
||||||
|
{
|
||||||
|
if ((pDib)&&(head.biClrUsed)){
|
||||||
|
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
|
||||||
|
if (idx<head.biClrUsed){
|
||||||
|
int32_t ldx=idx*sizeof(RGBQUAD);
|
||||||
|
iDst[ldx++] = (uint8_t) c.rgbBlue;
|
||||||
|
iDst[ldx++] = (uint8_t) c.rgbGreen;
|
||||||
|
iDst[ldx++] = (uint8_t) c.rgbRed;
|
||||||
|
iDst[ldx] = (uint8_t) c.rgbReserved;
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPaletteColor(uint8_t idx, COLORREF cr)
|
||||||
|
{
|
||||||
|
if ((pDib)&&(head.biClrUsed)){
|
||||||
|
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
|
||||||
|
if (idx<head.biClrUsed){
|
||||||
|
int32_t ldx=idx*sizeof(RGBQUAD);
|
||||||
|
iDst[ldx++] = (uint8_t) GetBValue(cr);
|
||||||
|
iDst[ldx++] = (uint8_t) GetGValue(cr);
|
||||||
|
iDst[ldx++] = (uint8_t) GetRValue(cr);
|
||||||
|
iDst[ldx] = (uint8_t) 0;
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* returns the pointer to the first palette index
|
||||||
|
*/
|
||||||
|
RGBQUAD* CxImage::GetPalette() const
|
||||||
|
{
|
||||||
|
if ((pDib)&&(head.biClrUsed))
|
||||||
|
return (RGBQUAD*)((uint8_t*)pDib + sizeof(BITMAPINFOHEADER));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns the color of the specified index.
|
||||||
|
*/
|
||||||
|
RGBQUAD CxImage::GetPaletteColor(uint8_t idx)
|
||||||
|
{
|
||||||
|
RGBQUAD rgb = {0,0,0,0};
|
||||||
|
if ((pDib)&&(head.biClrUsed)){
|
||||||
|
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
|
||||||
|
if (idx<head.biClrUsed){
|
||||||
|
int32_t ldx=idx*sizeof(RGBQUAD);
|
||||||
|
rgb.rgbBlue = iDst[ldx++];
|
||||||
|
rgb.rgbGreen=iDst[ldx++];
|
||||||
|
rgb.rgbRed =iDst[ldx++];
|
||||||
|
rgb.rgbReserved = iDst[ldx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns the palette index of the specified pixel.
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::GetPixelIndex(int32_t x,int32_t y)
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
|
||||||
|
|
||||||
|
if ((x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) {
|
||||||
|
if (info.nBkgndIndex >= 0) return (uint8_t)info.nBkgndIndex;
|
||||||
|
else return *info.pImage;
|
||||||
|
}
|
||||||
|
if (head.biBitCount==8){
|
||||||
|
return info.pImage[y*info.dwEffWidth + x];
|
||||||
|
} else {
|
||||||
|
uint8_t pos;
|
||||||
|
uint8_t iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
|
||||||
|
if (head.biBitCount==4){
|
||||||
|
pos = (uint8_t)(4*(1-x%2));
|
||||||
|
iDst &= (0x0F<<pos);
|
||||||
|
return (uint8_t)(iDst >> pos);
|
||||||
|
} else if (head.biBitCount==1){
|
||||||
|
pos = (uint8_t)(7-x%8);
|
||||||
|
iDst &= (0x01<<pos);
|
||||||
|
return (uint8_t)(iDst >> pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint8_t CxImage::BlindGetPixelIndex(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if ((pDib==NULL) || (head.biClrUsed==0) || !IsInside(x,y))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (head.biBitCount==8){
|
||||||
|
return info.pImage[y*info.dwEffWidth + x];
|
||||||
|
} else {
|
||||||
|
uint8_t pos;
|
||||||
|
uint8_t iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
|
||||||
|
if (head.biBitCount==4){
|
||||||
|
pos = (uint8_t)(4*(1-x%2));
|
||||||
|
iDst &= (0x0F<<pos);
|
||||||
|
return (uint8_t)(iDst >> pos);
|
||||||
|
} else if (head.biBitCount==1){
|
||||||
|
pos = (uint8_t)(7-x%8);
|
||||||
|
iDst &= (0x01<<pos);
|
||||||
|
return (uint8_t)(iDst >> pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RGBQUAD CxImage::GetPixelColor(int32_t x,int32_t y, bool bGetAlpha)
|
||||||
|
{
|
||||||
|
// RGBQUAD rgb={0,0,0,0};
|
||||||
|
RGBQUAD rgb=info.nBkgndColor; //<mpwolski>
|
||||||
|
if ((pDib==NULL)||(x<0)||(y<0)||
|
||||||
|
(x>=head.biWidth)||(y>=head.biHeight)){
|
||||||
|
if (info.nBkgndIndex >= 0){
|
||||||
|
if (head.biBitCount<24) return GetPaletteColor((uint8_t)info.nBkgndIndex);
|
||||||
|
else return info.nBkgndColor;
|
||||||
|
} else if (pDib) return GetPixelColor(0,0);
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.biClrUsed){
|
||||||
|
rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
|
||||||
|
} else {
|
||||||
|
uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
||||||
|
rgb.rgbBlue = *iDst++;
|
||||||
|
rgb.rgbGreen= *iDst++;
|
||||||
|
rgb.rgbRed = *iDst;
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
|
||||||
|
#else
|
||||||
|
rgb.rgbReserved = 0;
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* This is (a bit) faster version of GetPixelColor.
|
||||||
|
* It tests bounds only in debug mode (_DEBUG defined).
|
||||||
|
*
|
||||||
|
* It is an error to request out-of-borders pixel with this method.
|
||||||
|
* In DEBUG mode an exception will be thrown, and data will be violated in non-DEBUG mode.
|
||||||
|
* \author ***bd*** 2.2004
|
||||||
|
*/
|
||||||
|
RGBQUAD CxImage::BlindGetPixelColor(const int32_t x,const int32_t y, bool bGetAlpha)
|
||||||
|
{
|
||||||
|
RGBQUAD rgb;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if ((pDib==NULL) || !IsInside(x,y))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
{rgb.rgbReserved = 0; return rgb;}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (head.biClrUsed){
|
||||||
|
rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
|
||||||
|
} else {
|
||||||
|
uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
||||||
|
rgb.rgbBlue = *iDst++;
|
||||||
|
rgb.rgbGreen= *iDst++;
|
||||||
|
rgb.rgbRed = *iDst;
|
||||||
|
rgb.rgbReserved = 0; //needed for images without alpha layer
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
|
||||||
|
#else
|
||||||
|
rgb.rgbReserved = 0;
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint8_t CxImage::GetPixelGray(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
RGBQUAD color = GetPixelColor(x,y);
|
||||||
|
return (uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::BlindSetPixelIndex(int32_t x,int32_t y,uint8_t i)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if ((pDib==NULL)||(head.biClrUsed==0)||
|
||||||
|
(x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (head.biBitCount==8){
|
||||||
|
info.pImage[y*info.dwEffWidth + x]=i;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
uint8_t pos;
|
||||||
|
uint8_t* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
|
||||||
|
if (head.biBitCount==4){
|
||||||
|
pos = (uint8_t)(4*(1-x%2));
|
||||||
|
*iDst &= ~(0x0F<<pos);
|
||||||
|
*iDst |= ((i & 0x0F)<<pos);
|
||||||
|
return;
|
||||||
|
} else if (head.biBitCount==1){
|
||||||
|
pos = (uint8_t)(7-x%8);
|
||||||
|
*iDst &= ~(0x01<<pos);
|
||||||
|
*iDst |= ((i & 0x01)<<pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPixelIndex(int32_t x,int32_t y,uint8_t i)
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(head.biClrUsed==0)||
|
||||||
|
(x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) return ;
|
||||||
|
|
||||||
|
if (head.biBitCount==8){
|
||||||
|
info.pImage[y*info.dwEffWidth + x]=i;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
uint8_t pos;
|
||||||
|
uint8_t* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
|
||||||
|
if (head.biBitCount==4){
|
||||||
|
pos = (uint8_t)(4*(1-x%2));
|
||||||
|
*iDst &= ~(0x0F<<pos);
|
||||||
|
*iDst |= ((i & 0x0F)<<pos);
|
||||||
|
return;
|
||||||
|
} else if (head.biBitCount==1){
|
||||||
|
pos = (uint8_t)(7-x%8);
|
||||||
|
*iDst &= ~(0x01<<pos);
|
||||||
|
*iDst |= ((i & 0x01)<<pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPixelColor(int32_t x,int32_t y,COLORREF cr)
|
||||||
|
{
|
||||||
|
SetPixelColor(x,y,RGBtoRGBQUAD(cr));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::BlindSetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if ((pDib==NULL)||(x<0)||(y<0)||
|
||||||
|
(x>=head.biWidth)||(y>=head.biHeight))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
if (head.biClrUsed)
|
||||||
|
BlindSetPixelIndex(x,y,GetNearestIndex(c));
|
||||||
|
else {
|
||||||
|
uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
||||||
|
*iDst++ = c.rgbBlue;
|
||||||
|
*iDst++ = c.rgbGreen;
|
||||||
|
*iDst = c.rgbRed;
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha)
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(x<0)||(y<0)||
|
||||||
|
(x>=head.biWidth)||(y>=head.biHeight)) return;
|
||||||
|
if (head.biClrUsed)
|
||||||
|
BlindSetPixelIndex(x,y,GetNearestIndex(c));
|
||||||
|
else {
|
||||||
|
uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
||||||
|
*iDst++ = c.rgbBlue;
|
||||||
|
*iDst++ = c.rgbGreen;
|
||||||
|
*iDst = c.rgbRed;
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Blends the current pixel color with a new color.
|
||||||
|
* \param x,y = pixel
|
||||||
|
* \param c = new color
|
||||||
|
* \param blend = can be from 0 (no effect) to 1 (full effect).
|
||||||
|
* \param bSetAlpha = if true, blends also the alpha component stored in c.rgbReserved
|
||||||
|
*/
|
||||||
|
void CxImage::BlendPixelColor(int32_t x,int32_t y,RGBQUAD c, float blend, bool bSetAlpha)
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(x<0)||(y<0)||
|
||||||
|
(x>=head.biWidth)||(y>=head.biHeight)) return;
|
||||||
|
|
||||||
|
int32_t a0 = (int32_t)(256*blend);
|
||||||
|
int32_t a1 = 256 - a0;
|
||||||
|
|
||||||
|
RGBQUAD c0 = BlindGetPixelColor(x,y);
|
||||||
|
c.rgbRed = (uint8_t)((c.rgbRed * a0 + c0.rgbRed * a1)>>8);
|
||||||
|
c.rgbBlue = (uint8_t)((c.rgbBlue * a0 + c0.rgbBlue * a1)>>8);
|
||||||
|
c.rgbGreen = (uint8_t)((c.rgbGreen * a0 + c0.rgbGreen * a1)>>8);
|
||||||
|
|
||||||
|
if (head.biClrUsed)
|
||||||
|
BlindSetPixelIndex(x,y,GetNearestIndex(c));
|
||||||
|
else {
|
||||||
|
uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
|
||||||
|
*iDst++ = c.rgbBlue;
|
||||||
|
*iDst++ = c.rgbGreen;
|
||||||
|
*iDst = c.rgbRed;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns the best palette index that matches a specified color.
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::GetNearestIndex(RGBQUAD c)
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
|
||||||
|
|
||||||
|
// <RJ> check matching with the previous result
|
||||||
|
if (info.last_c_isvalid && (*(int32_t*)&info.last_c == *(int32_t*)&c)) return info.last_c_index;
|
||||||
|
info.last_c = c;
|
||||||
|
info.last_c_isvalid = true;
|
||||||
|
|
||||||
|
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
|
||||||
|
int32_t distance=200000;
|
||||||
|
int32_t i,j = 0;
|
||||||
|
int32_t k,l;
|
||||||
|
int32_t m = (int32_t)(head.biClrImportant==0 ? head.biClrUsed : head.biClrImportant);
|
||||||
|
for(i=0,l=0;i<m;i++,l+=sizeof(RGBQUAD)){
|
||||||
|
k = (iDst[l]-c.rgbBlue)*(iDst[l]-c.rgbBlue)+
|
||||||
|
(iDst[l+1]-c.rgbGreen)*(iDst[l+1]-c.rgbGreen)+
|
||||||
|
(iDst[l+2]-c.rgbRed)*(iDst[l+2]-c.rgbRed);
|
||||||
|
// k = abs(iDst[l]-c.rgbBlue)+abs(iDst[l+1]-c.rgbGreen)+abs(iDst[l+2]-c.rgbRed);
|
||||||
|
if (k==0){
|
||||||
|
j=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (k<distance){
|
||||||
|
distance=k;
|
||||||
|
j=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.last_c_index = (uint8_t)j;
|
||||||
|
return (uint8_t)j;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* swaps the blue and red components (for RGB images)
|
||||||
|
* \param buffer : pointer to the pixels
|
||||||
|
* \param length : number of bytes to swap. lenght may not exceed the scan line.
|
||||||
|
*/
|
||||||
|
void CxImage::RGBtoBGR(uint8_t *buffer, int32_t length)
|
||||||
|
{
|
||||||
|
if (buffer && (head.biClrUsed==0)){
|
||||||
|
uint8_t temp;
|
||||||
|
length = min(length,(int32_t)info.dwEffWidth);
|
||||||
|
length = min(length,(int32_t)(3*head.biWidth));
|
||||||
|
for (int32_t i=0;i<length;i+=3){
|
||||||
|
temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RGBQUAD CxImage::RGBtoRGBQUAD(COLORREF cr)
|
||||||
|
{
|
||||||
|
RGBQUAD c;
|
||||||
|
c.rgbRed = GetRValue(cr); /* get R, G, and B out of uint32_t */
|
||||||
|
c.rgbGreen = GetGValue(cr);
|
||||||
|
c.rgbBlue = GetBValue(cr);
|
||||||
|
c.rgbReserved=0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
COLORREF CxImage::RGBQUADtoRGB (RGBQUAD c)
|
||||||
|
{
|
||||||
|
return RGB(c.rgbRed,c.rgbGreen,c.rgbBlue);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns the color of the specified index.
|
||||||
|
* \param i = palette index
|
||||||
|
* \param r, g, b = output color channels
|
||||||
|
*/
|
||||||
|
bool CxImage::GetPaletteColor(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b)
|
||||||
|
{
|
||||||
|
RGBQUAD* ppal=GetPalette();
|
||||||
|
if (ppal) {
|
||||||
|
*r = ppal[i].rgbRed;
|
||||||
|
*g = ppal[i].rgbGreen;
|
||||||
|
*b = ppal[i].rgbBlue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPalette(uint32_t n, uint8_t *r, uint8_t *g, uint8_t *b)
|
||||||
|
{
|
||||||
|
if ((!r)||(pDib==NULL)||(head.biClrUsed==0)) return;
|
||||||
|
if (!g) g = r;
|
||||||
|
if (!b) b = g;
|
||||||
|
RGBQUAD* ppal=GetPalette();
|
||||||
|
uint32_t m=min(n,head.biClrUsed);
|
||||||
|
for (uint32_t i=0; i<m;i++){
|
||||||
|
ppal[i].rgbRed=r[i];
|
||||||
|
ppal[i].rgbGreen=g[i];
|
||||||
|
ppal[i].rgbBlue=b[i];
|
||||||
|
}
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPalette(rgb_color *rgb,uint32_t nColors)
|
||||||
|
{
|
||||||
|
if ((!rgb)||(pDib==NULL)||(head.biClrUsed==0)) return;
|
||||||
|
RGBQUAD* ppal=GetPalette();
|
||||||
|
uint32_t m=min(nColors,head.biClrUsed);
|
||||||
|
for (uint32_t i=0; i<m;i++){
|
||||||
|
ppal[i].rgbRed=rgb[i].r;
|
||||||
|
ppal[i].rgbGreen=rgb[i].g;
|
||||||
|
ppal[i].rgbBlue=rgb[i].b;
|
||||||
|
}
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::SetPalette(RGBQUAD* pPal,uint32_t nColors)
|
||||||
|
{
|
||||||
|
if ((pPal==NULL)||(pDib==NULL)||(head.biClrUsed==0)) return;
|
||||||
|
memcpy(GetPalette(),pPal,min(GetPaletteSize(),nColors*sizeof(RGBQUAD)));
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets (or replaces) the palette to gray scale palette.
|
||||||
|
* The function doesn't change the pixels; for standard
|
||||||
|
* gray scale conversion use GrayScale().
|
||||||
|
*/
|
||||||
|
void CxImage::SetGrayPalette()
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(head.biClrUsed==0)) return;
|
||||||
|
RGBQUAD* pal=GetPalette();
|
||||||
|
for (uint32_t ni=0;ni<head.biClrUsed;ni++)
|
||||||
|
pal[ni].rgbBlue=pal[ni].rgbGreen = pal[ni].rgbRed = (uint8_t)(ni*(255/(head.biClrUsed-1)));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Colorize the palette.
|
||||||
|
* \sa Colorize
|
||||||
|
*/
|
||||||
|
void CxImage::BlendPalette(COLORREF cr,int32_t perc)
|
||||||
|
{
|
||||||
|
if ((pDib==NULL)||(head.biClrUsed==0)) return;
|
||||||
|
uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
|
||||||
|
uint32_t i,r,g,b;
|
||||||
|
RGBQUAD* pPal=(RGBQUAD*)iDst;
|
||||||
|
r = GetRValue(cr);
|
||||||
|
g = GetGValue(cr);
|
||||||
|
b = GetBValue(cr);
|
||||||
|
if (perc>100) perc=100;
|
||||||
|
for(i=0;i<head.biClrUsed;i++){
|
||||||
|
pPal[i].rgbBlue=(uint8_t)((pPal[i].rgbBlue*(100-perc)+b*perc)/100);
|
||||||
|
pPal[i].rgbGreen =(uint8_t)((pPal[i].rgbGreen*(100-perc)+g*perc)/100);
|
||||||
|
pPal[i].rgbRed =(uint8_t)((pPal[i].rgbRed*(100-perc)+r*perc)/100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns true if the image has 256 colors and a linear grey scale palette.
|
||||||
|
*/
|
||||||
|
bool CxImage::IsGrayScale()
|
||||||
|
{
|
||||||
|
RGBQUAD* ppal=GetPalette();
|
||||||
|
if(!(pDib && ppal && head.biClrUsed)) return false;
|
||||||
|
for(uint32_t i=0;i<head.biClrUsed;i++){
|
||||||
|
if (ppal[i].rgbBlue!=i || ppal[i].rgbGreen!=i || ppal[i].rgbRed!=i) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* swap two indexes in the image and their colors in the palette
|
||||||
|
*/
|
||||||
|
void CxImage::SwapIndex(uint8_t idx1, uint8_t idx2)
|
||||||
|
{
|
||||||
|
RGBQUAD* ppal=GetPalette();
|
||||||
|
if(!(pDib && ppal)) return;
|
||||||
|
//swap the colors
|
||||||
|
RGBQUAD tempRGB=GetPaletteColor(idx1);
|
||||||
|
SetPaletteColor(idx1,GetPaletteColor(idx2));
|
||||||
|
SetPaletteColor(idx2,tempRGB);
|
||||||
|
//swap the pixels
|
||||||
|
uint8_t idx;
|
||||||
|
for(int32_t y=0; y < head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x < head.biWidth; x++){
|
||||||
|
idx=BlindGetPixelIndex(x,y);
|
||||||
|
if (idx==idx1) BlindSetPixelIndex(x,y,idx2);
|
||||||
|
if (idx==idx2) BlindSetPixelIndex(x,y,idx1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* swap Red and Blue colors
|
||||||
|
*/
|
||||||
|
void CxImage::SwapRGB2BGR()
|
||||||
|
{
|
||||||
|
if (!pDib) return;
|
||||||
|
|
||||||
|
if (head.biClrUsed){
|
||||||
|
RGBQUAD* ppal=GetPalette();
|
||||||
|
uint8_t b;
|
||||||
|
if(!ppal) return;
|
||||||
|
for(uint16_t a=0;a<head.biClrUsed;a++){
|
||||||
|
b=ppal[a].rgbBlue; ppal[a].rgbBlue=ppal[a].rgbRed; ppal[a].rgbRed=b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int32_t y=0;y<head.biHeight;y++){
|
||||||
|
RGBtoBGR(GetBits(y),3*head.biWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::IsTransparent(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
|
||||||
|
if (info.nBkgndIndex>=0){
|
||||||
|
if (head.biClrUsed){
|
||||||
|
if (GetPixelIndex(x,y) == info.nBkgndIndex) return true;
|
||||||
|
} else {
|
||||||
|
RGBQUAD ct = info.nBkgndColor;
|
||||||
|
RGBQUAD c = GetPixelColor(x,y,false);
|
||||||
|
if (*(int32_t*)&c==*(int32_t*)&ct) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pAlpha) return AlphaGet(x,y)==0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::GetTransparentMask(CxImage* iDst)
|
||||||
|
{
|
||||||
|
if (!pDib) return false;
|
||||||
|
|
||||||
|
CxImage tmp;
|
||||||
|
tmp.Create(head.biWidth, head.biHeight, 1, GetType());
|
||||||
|
tmp.SetStdPalette();
|
||||||
|
tmp.Clear(0);
|
||||||
|
|
||||||
|
for(int32_t y=0; y<head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x<head.biWidth; x++){
|
||||||
|
if (IsTransparent(x,y)){
|
||||||
|
tmp.BlindSetPixelIndex(x,y,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iDst) iDst->Transfer(tmp);
|
||||||
|
else Transfer(tmp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if image has the same palette, if any.
|
||||||
|
* \param img = image to compare.
|
||||||
|
* \param bCheckAlpha = check also the rgbReserved field.
|
||||||
|
*/
|
||||||
|
bool CxImage::IsSamePalette(CxImage &img, bool bCheckAlpha)
|
||||||
|
{
|
||||||
|
if (head.biClrUsed != img.head.biClrUsed)
|
||||||
|
return false;
|
||||||
|
if (head.biClrUsed == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RGBQUAD c1,c2;
|
||||||
|
for (uint32_t n=0; n<head.biClrUsed; n++){
|
||||||
|
c1 = GetPaletteColor((uint8_t)n);
|
||||||
|
c2 = img.GetPaletteColor((uint8_t)n);
|
||||||
|
if (c1.rgbRed != c2.rgbRed) return false;
|
||||||
|
if (c1.rgbBlue != c2.rgbBlue) return false;
|
||||||
|
if (c1.rgbGreen != c2.rgbGreen) return false;
|
||||||
|
if (bCheckAlpha && (c1.rgbReserved != c2.rgbReserved)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* \sa SetClrImportant
|
||||||
|
*/
|
||||||
|
uint32_t CxImage::GetClrImportant() const
|
||||||
|
{
|
||||||
|
return head.biClrImportant;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* sets the maximum number of colors that some functions like
|
||||||
|
* DecreaseBpp() or GetNearestIndex() will use on indexed images
|
||||||
|
* \param ncolors should be less than 2^bpp,
|
||||||
|
* or 0 if all the colors are important.
|
||||||
|
*/
|
||||||
|
void CxImage::SetClrImportant(uint32_t ncolors)
|
||||||
|
{
|
||||||
|
if (ncolors==0 || ncolors>256) {
|
||||||
|
head.biClrImportant = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(head.biBitCount){
|
||||||
|
case 1:
|
||||||
|
head.biClrImportant = min(ncolors,2);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
head.biClrImportant = min(ncolors,16);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
head.biClrImportant = ncolors;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns pointer to pixel. Currently implemented only for truecolor images.
|
||||||
|
*
|
||||||
|
* \param x,y - coordinates
|
||||||
|
*
|
||||||
|
* \return pointer to first byte of pixel data
|
||||||
|
*
|
||||||
|
* \author ***bd*** 2.2004
|
||||||
|
*/
|
||||||
|
void* CxImage::BlindGetPixelPointer(const int32_t x, const int32_t y)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if ((pDib==NULL) || !IsInside(x,y))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
if (!IsIndexed())
|
||||||
|
return info.pImage + y*info.dwEffWidth + x*3;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, COLORREF cr)
|
||||||
|
{
|
||||||
|
DrawLine(StartX, EndX, StartY, EndY, RGBtoRGBQUAD(cr));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImage::DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, RGBQUAD color, bool bSetAlpha)
|
||||||
|
{
|
||||||
|
if (!pDib) return;
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Draws a line using the Bresenham line algorithm
|
||||||
|
// Thanks to Jordan DeLozier <JDL>
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
int32_t x1 = StartX;
|
||||||
|
int32_t y1 = StartY;
|
||||||
|
int32_t x = x1; // Start x off at the first pixel
|
||||||
|
int32_t y = y1; // Start y off at the first pixel
|
||||||
|
int32_t x2 = EndX;
|
||||||
|
int32_t y2 = EndY;
|
||||||
|
|
||||||
|
int32_t xinc1,xinc2,yinc1,yinc2; // Increasing values
|
||||||
|
int32_t den, num, numadd,numpixels;
|
||||||
|
int32_t deltax = abs(x2 - x1); // The difference between the x's
|
||||||
|
int32_t deltay = abs(y2 - y1); // The difference between the y's
|
||||||
|
|
||||||
|
// Get Increasing Values
|
||||||
|
if (x2 >= x1) { // The x-values are increasing
|
||||||
|
xinc1 = 1;
|
||||||
|
xinc2 = 1;
|
||||||
|
} else { // The x-values are decreasing
|
||||||
|
xinc1 = -1;
|
||||||
|
xinc2 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y2 >= y1) { // The y-values are increasing
|
||||||
|
yinc1 = 1;
|
||||||
|
yinc2 = 1;
|
||||||
|
} else { // The y-values are decreasing
|
||||||
|
yinc1 = -1;
|
||||||
|
yinc2 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually draw the line
|
||||||
|
if (deltax >= deltay) // There is at least one x-value for every y-value
|
||||||
|
{
|
||||||
|
xinc1 = 0; // Don't change the x when numerator >= denominator
|
||||||
|
yinc2 = 0; // Don't change the y for every iteration
|
||||||
|
den = deltax;
|
||||||
|
num = deltax / 2;
|
||||||
|
numadd = deltay;
|
||||||
|
numpixels = deltax; // There are more x-values than y-values
|
||||||
|
}
|
||||||
|
else // There is at least one y-value for every x-value
|
||||||
|
{
|
||||||
|
xinc2 = 0; // Don't change the x for every iteration
|
||||||
|
yinc1 = 0; // Don't change the y when numerator >= denominator
|
||||||
|
den = deltay;
|
||||||
|
num = deltay / 2;
|
||||||
|
numadd = deltax;
|
||||||
|
numpixels = deltay; // There are more y-values than x-values
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t curpixel = 0; curpixel <= numpixels; curpixel++)
|
||||||
|
{
|
||||||
|
// Draw the current pixel
|
||||||
|
SetPixelColor(x,y,color,bSetAlpha);
|
||||||
|
|
||||||
|
num += numadd; // Increase the numerator by the top of the fraction
|
||||||
|
if (num >= den) // Check if numerator >= denominator
|
||||||
|
{
|
||||||
|
num -= den; // Calculate the new numerator value
|
||||||
|
x += xinc1; // Change the x as appropriate
|
||||||
|
y += yinc1; // Change the y as appropriate
|
||||||
|
}
|
||||||
|
x += xinc2; // Change the x as appropriate
|
||||||
|
y += yinc2; // Change the y as appropriate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets a palette with standard colors for 1, 4 and 8 bpp images.
|
||||||
|
*/
|
||||||
|
void CxImage::SetStdPalette()
|
||||||
|
{
|
||||||
|
if (!pDib) return;
|
||||||
|
switch (head.biBitCount){
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
const uint8_t pal256[1024] = {0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
|
||||||
|
192,220,192,0,240,202,166,0,212,240,255,0,177,226,255,0,142,212,255,0,107,198,255,0,
|
||||||
|
72,184,255,0,37,170,255,0,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,
|
||||||
|
50,80,0,212,227,255,0,177,199,255,0,142,171,255,0,107,143,255,0,72,115,255,0,37,87,255,0,0,
|
||||||
|
85,255,0,0,73,220,0,0,61,185,0,0,49,150,0,0,37,115,0,0,25,80,0,212,212,255,0,177,177,255,0,
|
||||||
|
142,142,255,0,107,107,255,0,72,72,255,0,37,37,255,0,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,
|
||||||
|
0,0,115,0,0,0,80,0,227,212,255,0,199,177,255,0,171,142,255,0,143,107,255,0,115,72,255,0,
|
||||||
|
87,37,255,0,85,0,255,0,73,0,220,0,61,0,185,0,49,0,150,0,37,0,115,0,25,0,80,0,240,212,255,0,
|
||||||
|
226,177,255,0,212,142,255,0,198,107,255,0,184,72,255,0,170,37,255,0,170,0,255,0,146,0,220,0,
|
||||||
|
122,0,185,0,98,0,150,0,74,0,115,0,50,0,80,0,255,212,255,0,255,177,255,0,255,142,255,0,255,107,255,0,
|
||||||
|
255,72,255,0,255,37,255,0,254,0,254,0,220,0,220,0,185,0,185,0,150,0,150,0,115,0,115,0,80,0,80,0,
|
||||||
|
255,212,240,0,255,177,226,0,255,142,212,0,255,107,198,0,255,72,184,0,255,37,170,0,255,0,170,0,
|
||||||
|
220,0,146,0,185,0,122,0,150,0,98,0,115,0,74,0,80,0,50,0,255,212,227,0,255,177,199,0,255,142,171,0,
|
||||||
|
255,107,143,0,255,72,115,0,255,37,87,0,255,0,85,0,220,0,73,0,185,0,61,0,150,0,49,0,115,0,37,0,
|
||||||
|
80,0,25,0,255,212,212,0,255,177,177,0,255,142,142,0,255,107,107,0,255,72,72,0,255,37,37,0,254,0,
|
||||||
|
0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,0,255,227,212,0,255,199,177,0,255,171,142,0,
|
||||||
|
255,143,107,0,255,115,72,0,255,87,37,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,115,37,0,
|
||||||
|
0,80,25,0,0,255,240,212,0,255,226,177,0,255,212,142,0,255,198,107,0,255,184,72,0,255,170,37,0,
|
||||||
|
255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,0,255,255,212,0,255,255,177,0,
|
||||||
|
255,255,142,0,255,255,107,0,255,255,72,0,255,255,37,0,254,254,0,0,220,220,0,0,185,185,0,0,150,150,0,
|
||||||
|
0,115,115,0,0,80,80,0,0,240,255,212,0,226,255,177,0,212,255,142,0,198,255,107,0,184,255,72,0,
|
||||||
|
170,255,37,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,50,80,0,0,227,255,212,0,
|
||||||
|
199,255,177,0,171,255,142,0,143,255,107,0,115,255,72,0,87,255,37,0,85,255,0,0,73,220,0,0,61,185,0,
|
||||||
|
0,49,150,0,0,37,115,0,0,25,80,0,0,212,255,212,0,177,255,177,0,142,255,142,0,107,255,107,0,72,255,72,0,
|
||||||
|
37,255,37,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,212,255,227,0,177,255,199,0,
|
||||||
|
142,255,171,0,107,255,143,0,72,255,115,0,37,255,87,0,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,
|
||||||
|
115,37,0,0,80,25,0,212,255,240,0,177,255,226,0,142,255,212,0,107,255,198,0,72,255,184,0,37,255,170,0,
|
||||||
|
0,255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,212,255,255,0,177,255,255,0,
|
||||||
|
142,255,255,0,107,255,255,0,72,255,255,0,37,255,255,0,0,254,254,0,0,220,220,0,0,185,185,0,0,
|
||||||
|
150,150,0,0,115,115,0,0,80,80,0,242,242,242,0,230,230,230,0,218,218,218,0,206,206,206,0,194,194,194,0,
|
||||||
|
182,182,182,0,170,170,170,0,158,158,158,0,146,146,146,0,134,134,134,0,122,122,122,0,110,110,110,0,
|
||||||
|
98,98,98,0,86,86,86,0,74,74,74,0,62,62,62,0,50,50,50,0,38,38,38,0,26,26,26,0,14,14,14,0,240,251,255,0,
|
||||||
|
164,160,160,0,128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
|
||||||
|
memcpy(GetPalette(),pal256,1024);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
const uint8_t pal16[64]={0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
|
||||||
|
128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
|
||||||
|
memcpy(GetPalette(),pal16,64);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
const uint8_t pal2[8]={0,0,0,0,255,255,255,0};
|
||||||
|
memcpy(GetPalette(),pal2,8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.last_c_isvalid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
479
Raw2Bmp_MFC/include/ximapcx.cpp
Normal file
479
Raw2Bmp_MFC/include/ximapcx.cpp
Normal file
@@ -0,0 +1,479 @@
|
|||||||
|
/*
|
||||||
|
* File: ximapcx.cpp
|
||||||
|
* Purpose: Platform Independent PCX Image Class Loader and Writer
|
||||||
|
* 05/Jan/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*
|
||||||
|
* based on ppmtopcx.c - convert a portable pixmap to PCX
|
||||||
|
* Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
||||||
|
* based on ppmtopcx.c by Michael Davidson
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximapcx.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
|
||||||
|
#include "xmemfile.h"
|
||||||
|
|
||||||
|
#define PCX_MAGIC 0X0A // PCX magic number
|
||||||
|
#define PCX_256_COLORS 0X0C // magic number for 256 colors
|
||||||
|
#define PCX_HDR_SIZE 128 // size of PCX header
|
||||||
|
#define PCX_MAXCOLORS 256
|
||||||
|
#define PCX_MAXPLANES 4
|
||||||
|
#define PCX_MAXVAL 255
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImagePCX::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
PCXHEADER pcxHeader;
|
||||||
|
int32_t i, x, y, y2, nbytes, count, Height, Width;
|
||||||
|
uint8_t c, ColorMap[PCX_MAXCOLORS][3];
|
||||||
|
uint8_t *pcximage = NULL, *lpHead1 = NULL, *lpHead2 = NULL;
|
||||||
|
uint8_t *pcxplanes, *pcxpixels;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (hFile->Read(&pcxHeader,sizeof(PCXHEADER),1)==0) cx_throw("Can't read PCX image");
|
||||||
|
|
||||||
|
PCX_toh(&pcxHeader);
|
||||||
|
|
||||||
|
if (pcxHeader.Manufacturer != PCX_MAGIC) cx_throw("Error: Not a PCX file");
|
||||||
|
// Check for PCX run length encoding
|
||||||
|
if (pcxHeader.Encoding != 1) cx_throw("PCX file has unknown encoding scheme");
|
||||||
|
|
||||||
|
Width = (pcxHeader.Xmax - pcxHeader.Xmin) + 1;
|
||||||
|
Height = (pcxHeader.Ymax - pcxHeader.Ymin) + 1;
|
||||||
|
info.xDPI = pcxHeader.Hres;
|
||||||
|
info.yDPI = pcxHeader.Vres;
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = Width;
|
||||||
|
head.biHeight= Height;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_PCX;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that we can handle this image format
|
||||||
|
if (pcxHeader.ColorPlanes > 4)
|
||||||
|
cx_throw("Can't handle image with more than 4 planes");
|
||||||
|
|
||||||
|
// Create the image
|
||||||
|
if (pcxHeader.ColorPlanes >= 3 && pcxHeader.BitsPerPixel == 8){
|
||||||
|
Create (Width, Height, 24, CXIMAGE_FORMAT_PCX);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (pcxHeader.ColorPlanes==4) AlphaCreate();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
} else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 1)
|
||||||
|
Create (Width, Height, 4, CXIMAGE_FORMAT_PCX);
|
||||||
|
else
|
||||||
|
Create (Width, Height, pcxHeader.BitsPerPixel, CXIMAGE_FORMAT_PCX);
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
//Read the image and check if it's ok
|
||||||
|
nbytes = pcxHeader.BytesPerLine * pcxHeader.ColorPlanes * Height;
|
||||||
|
lpHead1 = pcximage = (uint8_t*)malloc(nbytes);
|
||||||
|
while (nbytes > 0){
|
||||||
|
if (hFile == NULL || hFile->Eof()) cx_throw("corrupted PCX");
|
||||||
|
|
||||||
|
hFile->Read(&c,1,1);
|
||||||
|
if ((c & 0XC0) != 0XC0){ // Repeated group
|
||||||
|
*pcximage++ = c;
|
||||||
|
--nbytes;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
count = c & 0X3F; // extract count
|
||||||
|
hFile->Read(&c,1,1);
|
||||||
|
if (count > nbytes) cx_throw("repeat count spans end of image");
|
||||||
|
|
||||||
|
nbytes -= count;
|
||||||
|
while (--count >=0) *pcximage++ = c;
|
||||||
|
}
|
||||||
|
pcximage = lpHead1;
|
||||||
|
|
||||||
|
//store the palette
|
||||||
|
for (i = 0; i < 16; i++){
|
||||||
|
ColorMap[i][0] = pcxHeader.ColorMap[i][0];
|
||||||
|
ColorMap[i][1] = pcxHeader.ColorMap[i][1];
|
||||||
|
ColorMap[i][2] = pcxHeader.ColorMap[i][2];
|
||||||
|
}
|
||||||
|
if (pcxHeader.BitsPerPixel == 8 && pcxHeader.ColorPlanes == 1){
|
||||||
|
hFile->Read(&c,1,1);
|
||||||
|
if (c != PCX_256_COLORS) cx_throw("bad color map signature");
|
||||||
|
|
||||||
|
for (i = 0; i < PCX_MAXCOLORS; i++){
|
||||||
|
hFile->Read(&ColorMap[i][0],1,1);
|
||||||
|
hFile->Read(&ColorMap[i][1],1,1);
|
||||||
|
hFile->Read(&ColorMap[i][2],1,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
|
||||||
|
ColorMap[0][0] = ColorMap[0][1] = ColorMap[0][2] = 0;
|
||||||
|
ColorMap[1][0] = ColorMap[1][1] = ColorMap[1][2] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t idx=0; idx<head.biClrUsed; idx++) SetPaletteColor((uint8_t)idx,ColorMap[idx][0],ColorMap[idx][1],ColorMap[idx][2]);
|
||||||
|
|
||||||
|
lpHead2 = pcxpixels = (uint8_t *)malloc(Width + pcxHeader.BytesPerLine * 8);
|
||||||
|
// Convert the image
|
||||||
|
for (y = 0; y < Height; y++){
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
y2=Height-1-y;
|
||||||
|
pcxpixels = lpHead2;
|
||||||
|
pcxplanes = pcximage + (y * pcxHeader.BytesPerLine * pcxHeader.ColorPlanes);
|
||||||
|
|
||||||
|
if (pcxHeader.ColorPlanes == 3 && pcxHeader.BitsPerPixel == 8){
|
||||||
|
// Deal with 24 bit color image
|
||||||
|
for (x = 0; x < Width; x++){
|
||||||
|
SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
} else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 8){
|
||||||
|
for (x = 0; x < Width; x++){
|
||||||
|
SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
|
||||||
|
AlphaSet(x,y2,pcxplanes[3*pcxHeader.BytesPerLine + x]);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
} else if (pcxHeader.ColorPlanes == 1) {
|
||||||
|
if (!PCX_UnpackPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
|
||||||
|
cx_throw("PCX_UnpackPixels: Can't handle packed pixels with more than 1 plane");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!PCX_PlanesToPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
|
||||||
|
cx_throw("PCX_PlanesToPixels: more than 4 planes or more than 1 bit per pixel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (x = 0; x < Width; x++) SetPixelIndex(x,y2,pcxpixels[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (lpHead1){ free(lpHead1); lpHead1 = NULL; }
|
||||||
|
if (lpHead2){ free(lpHead2); lpHead2 = NULL; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (lpHead1){ free(lpHead1); lpHead1 = NULL; }
|
||||||
|
if (lpHead2){ free(lpHead2); lpHead2 = NULL; }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImagePCX::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
PCXHEADER pcxHeader;
|
||||||
|
memset(&pcxHeader,0,sizeof(pcxHeader));
|
||||||
|
pcxHeader.Manufacturer = PCX_MAGIC;
|
||||||
|
pcxHeader.Version = 5;
|
||||||
|
pcxHeader.Encoding = 1;
|
||||||
|
pcxHeader.Xmin = 0;
|
||||||
|
pcxHeader.Ymin = 0;
|
||||||
|
pcxHeader.Xmax = (uint16_t)head.biWidth-1;
|
||||||
|
pcxHeader.Ymax = (uint16_t)head.biHeight-1;
|
||||||
|
pcxHeader.Hres = (uint16_t)info.xDPI;
|
||||||
|
pcxHeader.Vres = (uint16_t)info.yDPI;
|
||||||
|
pcxHeader.Reserved = 0;
|
||||||
|
pcxHeader.PaletteType = head.biClrUsed==0;
|
||||||
|
|
||||||
|
switch(head.biBitCount){
|
||||||
|
case 24:
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
pcxHeader.BitsPerPixel = 8;
|
||||||
|
pcxHeader.ColorPlanes = head.biClrUsed==0 ? 3 : 1;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (AlphaIsValid() && head.biClrUsed==0) pcxHeader.ColorPlanes =4;
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
pcxHeader.BytesPerLine = (uint16_t)head.biWidth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: //(4 1)
|
||||||
|
pcxHeader.BitsPerPixel = 1;
|
||||||
|
pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1;
|
||||||
|
pcxHeader.BytesPerLine = (uint16_t)((head.biWidth * pcxHeader.BitsPerPixel + 7)>>3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
|
||||||
|
pcxHeader.ColorMap[0][0] = pcxHeader.ColorMap[0][1] = pcxHeader.ColorMap[0][2] = 0;
|
||||||
|
pcxHeader.ColorMap[1][0] = pcxHeader.ColorMap[1][1] = pcxHeader.ColorMap[1][2] = 255;
|
||||||
|
}
|
||||||
|
if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 4){
|
||||||
|
RGBQUAD c;
|
||||||
|
for (int32_t i = 0; i < 16; i++){
|
||||||
|
c=GetPaletteColor(i);
|
||||||
|
pcxHeader.ColorMap[i][0] = c.rgbRed;
|
||||||
|
pcxHeader.ColorMap[i][1] = c.rgbGreen;
|
||||||
|
pcxHeader.ColorMap[i][2] = c.rgbBlue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pcxHeader.BytesPerLine = (pcxHeader.BytesPerLine + 1)&(~1);
|
||||||
|
|
||||||
|
PCX_toh(&pcxHeader);
|
||||||
|
if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 )
|
||||||
|
cx_throw("cannot write PCX header");
|
||||||
|
PCX_toh(&pcxHeader);
|
||||||
|
|
||||||
|
CxMemFile buffer;
|
||||||
|
buffer.Open();
|
||||||
|
|
||||||
|
uint8_t c,n;
|
||||||
|
int32_t x,y;
|
||||||
|
if (head.biClrUsed==0){
|
||||||
|
for (y = head.biHeight-1; y >=0 ; y--){
|
||||||
|
for (int32_t p=0; p<pcxHeader.ColorPlanes; p++){
|
||||||
|
c=n=0;
|
||||||
|
for (x = 0; x<head.biWidth; x++){
|
||||||
|
if (p==0)
|
||||||
|
PCX_PackPixels(BlindGetPixelColor(x,y).rgbRed,c,n,buffer);
|
||||||
|
else if (p==1)
|
||||||
|
PCX_PackPixels(BlindGetPixelColor(x,y).rgbGreen,c,n,buffer);
|
||||||
|
else if (p==2)
|
||||||
|
PCX_PackPixels(BlindGetPixelColor(x,y).rgbBlue,c,n,buffer);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
else if (p==3)
|
||||||
|
PCX_PackPixels(BlindAlphaGet(x,y),c,n,buffer);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
|
||||||
|
|
||||||
|
} else if (head.biBitCount==8) {
|
||||||
|
|
||||||
|
for (y = head.biHeight-1; y >=0 ; y--){
|
||||||
|
c=n=0;
|
||||||
|
for (x = 0; x<head.biWidth; x++){
|
||||||
|
PCX_PackPixels(GetPixelIndex(x,y),c,n,buffer);
|
||||||
|
}
|
||||||
|
PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
|
||||||
|
|
||||||
|
if (head.biBitCount == 8){
|
||||||
|
hFile->PutC(0x0C);
|
||||||
|
uint8_t* pal = (uint8_t*)malloc(768);
|
||||||
|
RGBQUAD c;
|
||||||
|
for (int32_t i=0;i<256;i++){
|
||||||
|
c=GetPaletteColor(i);
|
||||||
|
pal[3*i+0] = c.rgbRed;
|
||||||
|
pal[3*i+1] = c.rgbGreen;
|
||||||
|
pal[3*i+2] = c.rgbBlue;
|
||||||
|
}
|
||||||
|
hFile->Write(pal,768,1);
|
||||||
|
free(pal);
|
||||||
|
}
|
||||||
|
} else { //(head.biBitCount==4) || (head.biBitCount==1)
|
||||||
|
|
||||||
|
RGBQUAD *rgb = GetPalette();
|
||||||
|
bool binvert = false;
|
||||||
|
if (CompareColors(&rgb[0],&rgb[1])>0) binvert=(head.biBitCount==1);
|
||||||
|
|
||||||
|
uint8_t* plane = (uint8_t*)malloc(pcxHeader.BytesPerLine);
|
||||||
|
uint8_t* raw = (uint8_t*)malloc(head.biWidth);
|
||||||
|
|
||||||
|
for(y = head.biHeight-1; y >=0 ; y--) {
|
||||||
|
|
||||||
|
for( x = 0; x < head.biWidth; x++) raw[x] = (uint8_t)GetPixelIndex(x,y);
|
||||||
|
|
||||||
|
if (binvert) for( x = 0; x < head.biWidth; x++) raw[x] = 1-raw[x];
|
||||||
|
|
||||||
|
for( x = 0; x < pcxHeader.ColorPlanes; x++ ) {
|
||||||
|
PCX_PixelsToPlanes(raw, head.biWidth, plane, x);
|
||||||
|
PCX_PackPlanes(plane, pcxHeader.BytesPerLine, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(plane);
|
||||||
|
free(raw);
|
||||||
|
|
||||||
|
hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Convert multi-plane format into 1 pixel per byte
|
||||||
|
// from unpacked file data bitplanes[] into pixel row pixels[]
|
||||||
|
// image Height rows, with each row having planes image planes each
|
||||||
|
// bytesperline bytes
|
||||||
|
bool CxImagePCX::PCX_PlanesToPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel)
|
||||||
|
{
|
||||||
|
int32_t i, j, npixels;
|
||||||
|
uint8_t * p;
|
||||||
|
if (planes > 4) return false;
|
||||||
|
if (bitsperpixel != 1) return false;
|
||||||
|
|
||||||
|
// Clear the pixel buffer
|
||||||
|
npixels = (bytesperline * 8) / bitsperpixel;
|
||||||
|
p = pixels;
|
||||||
|
while (--npixels >= 0) *p++ = 0;
|
||||||
|
|
||||||
|
// Do the format conversion
|
||||||
|
for (i = 0; i < planes; i++){
|
||||||
|
int32_t pixbit, bits, mask;
|
||||||
|
p = pixels;
|
||||||
|
pixbit = (1 << i); // pixel bit for this plane
|
||||||
|
for (j = 0; j < bytesperline; j++){
|
||||||
|
bits = *bitplanes++;
|
||||||
|
for (mask = 0X80; mask != 0; mask >>= 1, p++)
|
||||||
|
if (bits & mask) *p |= pixbit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// convert packed pixel format into 1 pixel per byte
|
||||||
|
// from unpacked file data bitplanes[] into pixel row pixels[]
|
||||||
|
// image Height rows, with each row having planes image planes each
|
||||||
|
// bytesperline bytes
|
||||||
|
bool CxImagePCX::PCX_UnpackPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel)
|
||||||
|
{
|
||||||
|
register int32_t bits;
|
||||||
|
if (planes != 1) return false;
|
||||||
|
|
||||||
|
if (bitsperpixel == 8){ // 8 bits/pixels, no unpacking needed
|
||||||
|
while (bytesperline-- > 0) *pixels++ = *bitplanes++;
|
||||||
|
} else if (bitsperpixel == 4){ // 4 bits/pixel, two pixels per byte
|
||||||
|
while (bytesperline-- > 0){
|
||||||
|
bits = *bitplanes++;
|
||||||
|
*pixels++ = (uint8_t)((bits >> 4) & 0X0F);
|
||||||
|
*pixels++ = (uint8_t)((bits) & 0X0F);
|
||||||
|
}
|
||||||
|
} else if (bitsperpixel == 2){ // 2 bits/pixel, four pixels per byte
|
||||||
|
while (bytesperline-- > 0){
|
||||||
|
bits = *bitplanes++;
|
||||||
|
*pixels++ = (uint8_t)((bits >> 6) & 0X03);
|
||||||
|
*pixels++ = (uint8_t)((bits >> 4) & 0X03);
|
||||||
|
*pixels++ = (uint8_t)((bits >> 2) & 0X03);
|
||||||
|
*pixels++ = (uint8_t)((bits) & 0X03);
|
||||||
|
}
|
||||||
|
} else if (bitsperpixel == 1){ // 1 bits/pixel, 8 pixels per byte
|
||||||
|
while (bytesperline-- > 0){
|
||||||
|
bits = *bitplanes++;
|
||||||
|
*pixels++ = ((bits & 0X80) != 0);
|
||||||
|
*pixels++ = ((bits & 0X40) != 0);
|
||||||
|
*pixels++ = ((bits & 0X20) != 0);
|
||||||
|
*pixels++ = ((bits & 0X10) != 0);
|
||||||
|
*pixels++ = ((bits & 0X08) != 0);
|
||||||
|
*pixels++ = ((bits & 0X04) != 0);
|
||||||
|
*pixels++ = ((bits & 0X02) != 0);
|
||||||
|
*pixels++ = ((bits & 0X01) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, int32_t &l, CxFile &f)
|
||||||
|
* p = current pixel (-1 ends the line -2 ends odd line)
|
||||||
|
* c = previous pixel
|
||||||
|
* n = number of consecutive pixels
|
||||||
|
*/
|
||||||
|
void CxImagePCX::PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, CxFile &f)
|
||||||
|
{
|
||||||
|
if (p!=c && n){
|
||||||
|
if (n==1 && c<0xC0){
|
||||||
|
f.PutC(c);
|
||||||
|
} else {
|
||||||
|
f.PutC(0xC0|n);
|
||||||
|
f.PutC(c);
|
||||||
|
}
|
||||||
|
n=0;
|
||||||
|
}
|
||||||
|
if (n==0x3F) {
|
||||||
|
f.PutC(0xFF);
|
||||||
|
f.PutC(c);
|
||||||
|
n=0;
|
||||||
|
}
|
||||||
|
if (p==-2) f.PutC(0);
|
||||||
|
c=(uint8_t)p;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImagePCX::PCX_PackPlanes(uint8_t* buff, const int32_t size, CxFile &f)
|
||||||
|
{
|
||||||
|
uint8_t *start,*end;
|
||||||
|
uint8_t c, previous, count;
|
||||||
|
|
||||||
|
start = buff;
|
||||||
|
end = buff + size;
|
||||||
|
previous = *start++;
|
||||||
|
count = 1;
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
c = *start++;
|
||||||
|
if (c == previous && count < 63) {
|
||||||
|
++count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 1 || (previous & 0xc0) == 0xc0) {
|
||||||
|
f.PutC( count | 0xc0 );
|
||||||
|
}
|
||||||
|
f.PutC(previous);
|
||||||
|
previous = c;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 1 || (previous & 0xc0) == 0xc0) {
|
||||||
|
count |= 0xc0;
|
||||||
|
f.PutC(count);
|
||||||
|
}
|
||||||
|
f.PutC(previous);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImagePCX::PCX_PixelsToPlanes(uint8_t* raw, int32_t width, uint8_t* buf, int32_t plane)
|
||||||
|
{
|
||||||
|
int32_t cbit, x, mask;
|
||||||
|
uint8_t *cp = buf-1;
|
||||||
|
|
||||||
|
mask = 1 << plane;
|
||||||
|
cbit = -1;
|
||||||
|
for( x = 0; x < width; x++ ) {
|
||||||
|
if( cbit < 0 ) {
|
||||||
|
cbit = 7;
|
||||||
|
*++cp = 0;
|
||||||
|
}
|
||||||
|
if( raw[x] & mask )
|
||||||
|
*cp |= (1<<cbit);
|
||||||
|
--cbit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImagePCX::PCX_toh(PCXHEADER* p)
|
||||||
|
{
|
||||||
|
p->Xmin = m_ntohs(p->Xmin);
|
||||||
|
p->Ymin = m_ntohs(p->Ymin);
|
||||||
|
p->Xmax = m_ntohs(p->Xmax);
|
||||||
|
p->Ymax = m_ntohs(p->Ymax);
|
||||||
|
p->Hres = m_ntohs(p->Hres);
|
||||||
|
p->Vres = m_ntohs(p->Vres);
|
||||||
|
p->BytesPerLine = m_ntohs(p->BytesPerLine);
|
||||||
|
p->PaletteType = m_ntohs(p->PaletteType);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_PCX
|
||||||
64
Raw2Bmp_MFC/include/ximapcx.h
Normal file
64
Raw2Bmp_MFC/include/ximapcx.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* File: ximapcx.h
|
||||||
|
* Purpose: PCX Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImagePCX (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Parts of the code come from Paintlib: Copyright (c) 1996-1998 Ulrich von Zadow
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaPCX_h)
|
||||||
|
#define __ximaPCX_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PCX
|
||||||
|
|
||||||
|
class CxImagePCX: public CxImage
|
||||||
|
{
|
||||||
|
// PCX Image File
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct tagPCXHEADER
|
||||||
|
{
|
||||||
|
char Manufacturer; // always 0X0A
|
||||||
|
char Version; // version number
|
||||||
|
char Encoding; // always 1
|
||||||
|
char BitsPerPixel; // color bits
|
||||||
|
uint16_t Xmin, Ymin; // image origin
|
||||||
|
uint16_t Xmax, Ymax; // image dimensions
|
||||||
|
uint16_t Hres, Vres; // resolution values
|
||||||
|
uint8_t ColorMap[16][3]; // color palette
|
||||||
|
char Reserved;
|
||||||
|
char ColorPlanes; // color planes
|
||||||
|
uint16_t BytesPerLine; // line buffer size
|
||||||
|
uint16_t PaletteType; // grey or color palette
|
||||||
|
char Filter[58];
|
||||||
|
} PCXHEADER;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImagePCX(): CxImage(CXIMAGE_FORMAT_PCX) {}
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PCX);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PCX);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
protected:
|
||||||
|
bool PCX_PlanesToPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel);
|
||||||
|
bool PCX_UnpackPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel);
|
||||||
|
void PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, CxFile &f);
|
||||||
|
void PCX_PackPlanes(uint8_t* buff, const int32_t size, CxFile &f);
|
||||||
|
void PCX_PixelsToPlanes(uint8_t* raw, int32_t width, uint8_t* buf, int32_t plane);
|
||||||
|
void PCX_toh(PCXHEADER* p);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
553
Raw2Bmp_MFC/include/ximapng.cpp
Normal file
553
Raw2Bmp_MFC/include/ximapng.cpp
Normal file
@@ -0,0 +1,553 @@
|
|||||||
|
/*
|
||||||
|
* File: ximapng.cpp
|
||||||
|
* Purpose: Platform Independent PNG Image Class Loader and Writer
|
||||||
|
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximapng.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
|
||||||
|
#include "ximaiter.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImagePNG::ima_png_error(png_struct *png_ptr, char *message)
|
||||||
|
{
|
||||||
|
strcpy(info.szLastError,message);
|
||||||
|
longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImagePNG::expand2to4bpp(uint8_t* prow)
|
||||||
|
{
|
||||||
|
uint8_t *psrc,*pdst;
|
||||||
|
uint8_t pos,idx;
|
||||||
|
for(int32_t x=head.biWidth-1;x>=0;x--){
|
||||||
|
psrc = prow + ((2*x)>>3);
|
||||||
|
pdst = prow + ((4*x)>>3);
|
||||||
|
pos = (uint8_t)(2*(3-x%4));
|
||||||
|
idx = (uint8_t)((*psrc & (0x03<<pos))>>pos);
|
||||||
|
pos = (uint8_t)(4*(1-x%2));
|
||||||
|
*pdst &= ~(0x0F<<pos);
|
||||||
|
*pdst |= (idx & 0x0F)<<pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImagePNG::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
png_struct *png_ptr;
|
||||||
|
png_info *info_ptr;
|
||||||
|
uint8_t *row_pointers=NULL;
|
||||||
|
CImageIterator iter(this);
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
/* Create and initialize the png_struct with the desired error handler
|
||||||
|
* functions. If you want to use the default stderr and longjump method,
|
||||||
|
* you can supply NULL for the last three parameters. We also supply the
|
||||||
|
* the compiler header file version, so that we know if the application
|
||||||
|
* was compiled with a compatible version of the library. REQUIRED */
|
||||||
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,(void *)NULL,NULL,NULL);
|
||||||
|
if (png_ptr == NULL) cx_throw("Failed to create PNG structure");
|
||||||
|
|
||||||
|
/* Allocate/initialize the memory for image information. REQUIRED. */
|
||||||
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
if (info_ptr == NULL) {
|
||||||
|
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
||||||
|
cx_throw("Failed to initialize PNG info structure");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set error handling if you are using the setjmp/longjmp method (this is
|
||||||
|
* the normal method of doing things with libpng). REQUIRED unless you
|
||||||
|
* set up your own error handlers in the png_create_read_struct() earlier. */
|
||||||
|
if (setjmp(png_ptr->png_jmpbuf)) {
|
||||||
|
/* Free all of the memory associated with the png_ptr and info_ptr */
|
||||||
|
delete [] row_pointers;
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
|
cx_throw("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// use custom I/O functions
|
||||||
|
png_set_read_fn(png_ptr, hFile, /*(png_rw_ptr)*/user_read_data);
|
||||||
|
png_set_error_fn(png_ptr,info.szLastError,/*(png_error_ptr)*/user_error_fn,NULL);
|
||||||
|
|
||||||
|
/* read the file information */
|
||||||
|
png_read_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = info_ptr->width;
|
||||||
|
head.biHeight= info_ptr->height;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_PNG;
|
||||||
|
longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate new number of channels */
|
||||||
|
int32_t channels=0;
|
||||||
|
switch(info_ptr->color_type){
|
||||||
|
case PNG_COLOR_TYPE_GRAY:
|
||||||
|
case PNG_COLOR_TYPE_PALETTE:
|
||||||
|
channels = 1;
|
||||||
|
break;
|
||||||
|
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||||
|
channels = 2;
|
||||||
|
break;
|
||||||
|
case PNG_COLOR_TYPE_RGB:
|
||||||
|
channels = 3;
|
||||||
|
break;
|
||||||
|
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||||
|
channels = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy(info.szLastError,"unknown PNG color type");
|
||||||
|
longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//find the right pixel depth used for cximage
|
||||||
|
int32_t pixel_depth = info_ptr->pixel_depth;
|
||||||
|
if (channels == 1 && pixel_depth>8) pixel_depth=8;
|
||||||
|
if (channels == 2) pixel_depth=8;
|
||||||
|
if (channels >= 3) pixel_depth=24;
|
||||||
|
|
||||||
|
if (!Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG)){
|
||||||
|
longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get metrics */
|
||||||
|
switch (info_ptr->phys_unit_type)
|
||||||
|
{
|
||||||
|
case PNG_RESOLUTION_UNKNOWN:
|
||||||
|
SetXDPI(info_ptr->x_pixels_per_unit);
|
||||||
|
SetYDPI(info_ptr->y_pixels_per_unit);
|
||||||
|
break;
|
||||||
|
case PNG_RESOLUTION_METER:
|
||||||
|
SetXDPI((int32_t)floor(info_ptr->x_pixels_per_unit * 254.0 / 10000.0 + 0.5));
|
||||||
|
SetYDPI((int32_t)floor(info_ptr->y_pixels_per_unit * 254.0 / 10000.0 + 0.5));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info_ptr->num_palette>0){
|
||||||
|
SetPalette((rgb_color*)info_ptr->palette,info_ptr->num_palette);
|
||||||
|
SetClrImportant(info_ptr->num_palette);
|
||||||
|
} else if (info_ptr->bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs
|
||||||
|
SetPaletteColor(0,0,0,0);
|
||||||
|
SetPaletteColor(1,85,85,85);
|
||||||
|
SetPaletteColor(2,170,170,170);
|
||||||
|
SetPaletteColor(3,255,255,255);
|
||||||
|
} else SetGrayPalette(); //<DP> needed for grayscale PNGs
|
||||||
|
|
||||||
|
int32_t nshift = max(0,(info_ptr->bit_depth>>3)-1)<<3;
|
||||||
|
|
||||||
|
if (info_ptr->num_trans!=0){ //palette transparency
|
||||||
|
if (info_ptr->num_trans==1){
|
||||||
|
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE){
|
||||||
|
info.nBkgndIndex = info_ptr->trans_color.index;
|
||||||
|
} else{
|
||||||
|
info.nBkgndIndex = info_ptr->trans_color.gray>>nshift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (info_ptr->num_trans>1){
|
||||||
|
RGBQUAD* pal=GetPalette();
|
||||||
|
if (pal){
|
||||||
|
uint32_t ip;
|
||||||
|
for (ip=0;ip<min(head.biClrUsed,(uint32_t)info_ptr->num_trans);ip++)
|
||||||
|
pal[ip].rgbReserved=info_ptr->trans_alpha[ip];
|
||||||
|
for (ip=info_ptr->num_trans;ip<head.biClrUsed;ip++){
|
||||||
|
pal[ip].rgbReserved=255;
|
||||||
|
}
|
||||||
|
info.bAlphaPaletteEnabled=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channels == 3){ //check RGB binary transparency
|
||||||
|
png_bytep trans;
|
||||||
|
int32_t num_trans;
|
||||||
|
png_color_16 *image_background;
|
||||||
|
if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &image_background)){
|
||||||
|
info.nBkgndColor.rgbRed = (uint8_t)(info_ptr->trans_color.red>>nshift);
|
||||||
|
info.nBkgndColor.rgbGreen = (uint8_t)(info_ptr->trans_color.green>>nshift);
|
||||||
|
info.nBkgndColor.rgbBlue = (uint8_t)(info_ptr->trans_color.blue>>nshift);
|
||||||
|
info.nBkgndColor.rgbReserved = 0;
|
||||||
|
info.nBkgndIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t alpha_present = (channels - 1) % 2;
|
||||||
|
if (alpha_present){
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
AlphaCreate();
|
||||||
|
#else
|
||||||
|
png_set_strip_alpha(png_ptr);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
|
||||||
|
// <vho> - flip the RGB pixels to BGR (or RGBA to BGRA)
|
||||||
|
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR){
|
||||||
|
png_set_bgr(png_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// <vho> - handle cancel
|
||||||
|
if (info.nEscape) longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
|
||||||
|
// row_bytes is the width x number of channels x (bit-depth / 8)
|
||||||
|
row_pointers = new uint8_t[info_ptr->rowbytes + 8];
|
||||||
|
|
||||||
|
// turn on interlace handling
|
||||||
|
int32_t number_passes = png_set_interlace_handling(png_ptr);
|
||||||
|
|
||||||
|
if (number_passes>1){
|
||||||
|
SetCodecOption( (ENCODE_INTERLACE) | GetCodecOption(CXIMAGE_FORMAT_PNG));
|
||||||
|
} else {
|
||||||
|
SetCodecOption(~(ENCODE_INTERLACE) & GetCodecOption(CXIMAGE_FORMAT_PNG));
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t chan_offset = info_ptr->bit_depth >> 3;
|
||||||
|
int32_t pixel_offset = info_ptr->pixel_depth >> 3;
|
||||||
|
|
||||||
|
for (int32_t pass=0; pass < number_passes; pass++) {
|
||||||
|
iter.Upset();
|
||||||
|
int32_t y=0;
|
||||||
|
do {
|
||||||
|
|
||||||
|
// <vho> - handle cancel
|
||||||
|
if (info.nEscape) longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
if (AlphaIsValid()) {
|
||||||
|
|
||||||
|
//compute the correct position of the line
|
||||||
|
int32_t ax,ay;
|
||||||
|
ay = head.biHeight-1-y;
|
||||||
|
uint8_t* prow= iter.GetRow(ay);
|
||||||
|
|
||||||
|
//recover data from previous scan
|
||||||
|
if (info_ptr->interlace_type && pass>0 && pass!=7){
|
||||||
|
for(ax=0;ax<head.biWidth;ax++){
|
||||||
|
int32_t px = ax * pixel_offset;
|
||||||
|
if (channels == 2){
|
||||||
|
row_pointers[px] = prow[ax];
|
||||||
|
row_pointers[px+chan_offset]=AlphaGet(ax,ay);
|
||||||
|
} else {
|
||||||
|
int32_t qx = ax * 3;
|
||||||
|
row_pointers[px] =prow[qx];
|
||||||
|
row_pointers[px+chan_offset] =prow[qx+1];
|
||||||
|
row_pointers[px+chan_offset*2]=prow[qx+2];
|
||||||
|
row_pointers[px+chan_offset*3]=AlphaGet(ax,ay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//read next row
|
||||||
|
png_read_row(png_ptr, row_pointers, NULL);
|
||||||
|
|
||||||
|
//RGBA -> RGB + A
|
||||||
|
for(ax=0;ax<head.biWidth;ax++){
|
||||||
|
int32_t px = ax * pixel_offset;
|
||||||
|
if (channels == 2){
|
||||||
|
prow[ax] = row_pointers[px];
|
||||||
|
AlphaSet(ax,ay,row_pointers[px+chan_offset]);
|
||||||
|
} else {
|
||||||
|
int32_t qx = ax * 3;
|
||||||
|
prow[qx] =row_pointers[px];
|
||||||
|
prow[qx+1]=row_pointers[px+chan_offset];
|
||||||
|
prow[qx+2]=row_pointers[px+chan_offset*2];
|
||||||
|
AlphaSet(ax,ay,row_pointers[px+chan_offset*3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif // CXIMAGE_SUPPORT_ALPHA // vho
|
||||||
|
{
|
||||||
|
//recover data from previous scan
|
||||||
|
if (info_ptr->interlace_type && pass>0){
|
||||||
|
iter.GetRow(row_pointers, info_ptr->rowbytes);
|
||||||
|
//re-expand buffer for images with bit depth > 8
|
||||||
|
if (info_ptr->bit_depth > 8){
|
||||||
|
for(int32_t ax=(head.biWidth*channels-1);ax>=0;ax--)
|
||||||
|
row_pointers[ax*chan_offset] = row_pointers[ax];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//read next row
|
||||||
|
png_read_row(png_ptr, row_pointers, NULL);
|
||||||
|
|
||||||
|
//shrink 16 bit depth images down to 8 bits
|
||||||
|
if (info_ptr->bit_depth > 8){
|
||||||
|
for(int32_t ax=0;ax<(head.biWidth*channels);ax++)
|
||||||
|
row_pointers[ax] = row_pointers[ax*chan_offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the pixels
|
||||||
|
iter.SetRow(row_pointers, info_ptr->rowbytes);
|
||||||
|
//<DP> expand 2 bpp images only in the last pass
|
||||||
|
if (info_ptr->bit_depth==2 && pass==(number_passes-1))
|
||||||
|
expand2to4bpp(iter.GetRow());
|
||||||
|
|
||||||
|
//go on
|
||||||
|
iter.PrevRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
y++;
|
||||||
|
} while(y<head.biHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] row_pointers;
|
||||||
|
row_pointers = NULL;
|
||||||
|
|
||||||
|
/* read the rest of the file, getting any additional chunks in info_ptr - REQUIRED */
|
||||||
|
png_read_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* clean up after the read, and free any memory allocated - REQUIRED */
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_PNG) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* that's it */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImagePNG::Encode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
CImageIterator iter(this);
|
||||||
|
uint8_t trans[256]; //for transparency (don't move)
|
||||||
|
png_struct *png_ptr;
|
||||||
|
png_info *info_ptr;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
/* Create and initialize the png_struct with the desired error handler
|
||||||
|
* functions. If you want to use the default stderr and longjump method,
|
||||||
|
* you can supply NULL for the last three parameters. We also check that
|
||||||
|
* the library version is compatible with the one used at compile time,
|
||||||
|
* in case we are using dynamically linked libraries. REQUIRED.
|
||||||
|
*/
|
||||||
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,(void *)NULL,NULL,NULL);
|
||||||
|
if (png_ptr == NULL) cx_throw("Failed to create PNG structure");
|
||||||
|
|
||||||
|
/* Allocate/initialize the image information data. REQUIRED */
|
||||||
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
if (info_ptr == NULL){
|
||||||
|
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||||
|
cx_throw("Failed to initialize PNG info structure");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set error handling. REQUIRED if you aren't supplying your own
|
||||||
|
* error hadnling functions in the png_create_write_struct() call.
|
||||||
|
*/
|
||||||
|
if (setjmp(png_ptr->png_jmpbuf)){
|
||||||
|
/* If we get here, we had a problem reading the file */
|
||||||
|
if (info_ptr->palette) free(info_ptr->palette);
|
||||||
|
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
|
||||||
|
cx_throw("Error saving PNG file");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up the output control */
|
||||||
|
//png_init_io(png_ptr, hFile);
|
||||||
|
|
||||||
|
// use custom I/O functions
|
||||||
|
png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data);
|
||||||
|
|
||||||
|
/* set the file information here */
|
||||||
|
info_ptr->width = GetWidth();
|
||||||
|
info_ptr->height = GetHeight();
|
||||||
|
info_ptr->pixel_depth = (uint8_t)GetBpp();
|
||||||
|
info_ptr->channels = (GetBpp()>8) ? (uint8_t)3: (uint8_t)1;
|
||||||
|
info_ptr->bit_depth = (uint8_t)(GetBpp()/info_ptr->channels);
|
||||||
|
info_ptr->compression_type = info_ptr->filter_type = 0;
|
||||||
|
info_ptr->valid = 0;
|
||||||
|
|
||||||
|
// set interlace type
|
||||||
|
DWORD codec_opt = GetCodecOption(CXIMAGE_FORMAT_PNG);
|
||||||
|
if (codec_opt & CxImagePNG::ENCODE_INTERLACE)
|
||||||
|
info_ptr->interlace_type = PNG_INTERLACE_ADAM7;
|
||||||
|
else
|
||||||
|
info_ptr->interlace_type = PNG_INTERLACE_NONE;
|
||||||
|
|
||||||
|
/* set compression level */
|
||||||
|
int32_t compress_level;
|
||||||
|
switch (codec_opt & CxImagePNG::ENCODE_COMPRESSION_MASK)
|
||||||
|
{
|
||||||
|
case ENCODE_NO_COMPRESSION:
|
||||||
|
compress_level = Z_NO_COMPRESSION;
|
||||||
|
break;
|
||||||
|
case ENCODE_BEST_SPEED:
|
||||||
|
compress_level = Z_BEST_SPEED;
|
||||||
|
break;
|
||||||
|
case ENCODE_BEST_COMPRESSION:
|
||||||
|
compress_level = Z_BEST_COMPRESSION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
compress_level = Z_DEFAULT_COMPRESSION;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
png_set_compression_level(png_ptr, compress_level);
|
||||||
|
|
||||||
|
bool bGrayScale = IsGrayScale();
|
||||||
|
|
||||||
|
if (GetNumColors()){
|
||||||
|
if (bGrayScale){
|
||||||
|
info_ptr->color_type = PNG_COLOR_TYPE_GRAY;
|
||||||
|
} else {
|
||||||
|
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info_ptr->color_type = PNG_COLOR_TYPE_RGB;
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (AlphaIsValid()){
|
||||||
|
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
|
||||||
|
info_ptr->channels++;
|
||||||
|
info_ptr->bit_depth = 8;
|
||||||
|
info_ptr->pixel_depth += 8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set background */
|
||||||
|
png_color_16 image_background={ 0, 255, 255, 255, 0 };
|
||||||
|
RGBQUAD tc = GetTransColor();
|
||||||
|
if (info.nBkgndIndex>=0) {
|
||||||
|
image_background.blue = tc.rgbBlue;
|
||||||
|
image_background.green = tc.rgbGreen;
|
||||||
|
image_background.red = tc.rgbRed;
|
||||||
|
}
|
||||||
|
png_set_bKGD(png_ptr, info_ptr, &image_background);
|
||||||
|
|
||||||
|
/* set metrics */
|
||||||
|
png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER);
|
||||||
|
|
||||||
|
png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth,
|
||||||
|
info_ptr->color_type, info_ptr->interlace_type,
|
||||||
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||||
|
|
||||||
|
//<DP> simple transparency
|
||||||
|
if (info.nBkgndIndex >= 0){
|
||||||
|
info_ptr->num_trans = 1;
|
||||||
|
info_ptr->valid |= PNG_INFO_tRNS;
|
||||||
|
info_ptr->trans_alpha = trans;
|
||||||
|
info_ptr->trans_color.index = (uint8_t)info.nBkgndIndex;
|
||||||
|
info_ptr->trans_color.red = tc.rgbRed;
|
||||||
|
info_ptr->trans_color.green = tc.rgbGreen;
|
||||||
|
info_ptr->trans_color.blue = tc.rgbBlue;
|
||||||
|
info_ptr->trans_color.gray = info_ptr->trans_color.index;
|
||||||
|
|
||||||
|
// the transparency indexes start from 0 for non grayscale palette
|
||||||
|
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex)
|
||||||
|
SwapIndex(0,(uint8_t)info.nBkgndIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the palette if there is one */
|
||||||
|
if (GetPalette()){
|
||||||
|
if (!bGrayScale){
|
||||||
|
info_ptr->valid |= PNG_INFO_PLTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t nc = GetClrImportant();
|
||||||
|
if (nc==0) nc = GetNumColors();
|
||||||
|
|
||||||
|
if (info.bAlphaPaletteEnabled){
|
||||||
|
for(uint16_t ip=0; ip<nc;ip++)
|
||||||
|
trans[ip]=GetPaletteColor((uint8_t)ip).rgbReserved;
|
||||||
|
info_ptr->num_trans = (uint16_t)nc;
|
||||||
|
info_ptr->valid |= PNG_INFO_tRNS;
|
||||||
|
info_ptr->trans_alpha = trans;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the palette colors
|
||||||
|
info_ptr->palette = new png_color[nc];
|
||||||
|
info_ptr->num_palette = (png_uint_16) nc;
|
||||||
|
for (int32_t i=0; i<nc; i++)
|
||||||
|
GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
//Merge the transparent color with the alpha channel
|
||||||
|
if (AlphaIsValid() && head.biBitCount==24 && info.nBkgndIndex>=0){
|
||||||
|
for(int32_t y=0; y < head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x < head.biWidth ; x++){
|
||||||
|
RGBQUAD c=GetPixelColor(x,y,false);
|
||||||
|
if (*(int32_t*)&c==*(int32_t*)&tc)
|
||||||
|
AlphaSet(x,y,0);
|
||||||
|
} } }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
|
||||||
|
int32_t row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8));
|
||||||
|
info_ptr->rowbytes = row_size;
|
||||||
|
uint8_t *row_pointers = new uint8_t[row_size];
|
||||||
|
|
||||||
|
/* write the file information */
|
||||||
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
//interlace handling
|
||||||
|
int32_t num_pass = png_set_interlace_handling(png_ptr);
|
||||||
|
for (int32_t pass = 0; pass < num_pass; pass++){
|
||||||
|
//write image
|
||||||
|
iter.Upset();
|
||||||
|
int32_t ay=head.biHeight-1;
|
||||||
|
do {
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
RGBQUAD c;
|
||||||
|
if (AlphaIsValid()){
|
||||||
|
for (int32_t ax=head.biWidth-1; ax>=0;ax--){
|
||||||
|
c = BlindGetPixelColor(ax,ay);
|
||||||
|
int32_t px = ax * info_ptr->channels;
|
||||||
|
if (!bGrayScale){
|
||||||
|
row_pointers[px++]=c.rgbRed;
|
||||||
|
row_pointers[px++]=c.rgbGreen;
|
||||||
|
}
|
||||||
|
row_pointers[px++]=c.rgbBlue;
|
||||||
|
row_pointers[px] = AlphaGet(ax,ay);
|
||||||
|
}
|
||||||
|
png_write_row(png_ptr, row_pointers);
|
||||||
|
ay--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
{
|
||||||
|
iter.GetRow(row_pointers, row_size);
|
||||||
|
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP
|
||||||
|
RGBtoBGR(row_pointers, row_size);
|
||||||
|
png_write_row(png_ptr, row_pointers);
|
||||||
|
}
|
||||||
|
} while(iter.PrevRow());
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] row_pointers;
|
||||||
|
row_pointers = NULL;
|
||||||
|
|
||||||
|
//if necessary, restore the original palette
|
||||||
|
if (!bGrayScale && head.biClrUsed && info.nBkgndIndex>0)
|
||||||
|
SwapIndex((uint8_t)info.nBkgndIndex,0);
|
||||||
|
|
||||||
|
/* It is REQUIRED to call this to finish writing the rest of the file */
|
||||||
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
/* if you malloced the palette, free it here */
|
||||||
|
if (info_ptr->palette){
|
||||||
|
delete [] (info_ptr->palette);
|
||||||
|
info_ptr->palette = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up after the write, and free any memory allocated */
|
||||||
|
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* that's it */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_PNG
|
||||||
94
Raw2Bmp_MFC/include/ximapng.h
Normal file
94
Raw2Bmp_MFC/include/ximapng.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* File: ximapng.h
|
||||||
|
* Purpose: PNG Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImagePNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
|
||||||
|
*
|
||||||
|
* original CImagePNG and CImageIterator implementation are:
|
||||||
|
* Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
|
||||||
|
*
|
||||||
|
* libpng Copyright (c) 1998-2003 Glenn Randers-Pehrson
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaPNG_h)
|
||||||
|
#define __ximaPNG_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PNG
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#ifdef _LINUX
|
||||||
|
#undef _DLL
|
||||||
|
#include <png.h>
|
||||||
|
#include <pngstruct.h>
|
||||||
|
#include <pnginfo.h>
|
||||||
|
#else
|
||||||
|
#include "../png/png.h"
|
||||||
|
#include "../png/pngstruct.h"
|
||||||
|
#include "../png/pnginfo.h"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
class CxImagePNG: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImagePNG(): CxImage(CXIMAGE_FORMAT_PNG) {}
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PNG);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PNG);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
enum CODEC_OPTION
|
||||||
|
{
|
||||||
|
ENCODE_INTERLACE = 0x01,
|
||||||
|
// Exclusive compression types : 3 bit wide field
|
||||||
|
ENCODE_COMPRESSION_MASK = 0x0E,
|
||||||
|
ENCODE_NO_COMPRESSION = 1 << 1,
|
||||||
|
ENCODE_BEST_SPEED = 2 << 1,
|
||||||
|
ENCODE_BEST_COMPRESSION = 3 << 1,
|
||||||
|
ENCODE_DEFAULT_COMPRESSION = 4 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ima_png_error(png_struct *png_ptr, char *message);
|
||||||
|
void expand2to4bpp(uint8_t* prow);
|
||||||
|
|
||||||
|
static void PNGAPI user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||||
|
{
|
||||||
|
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
|
||||||
|
if (hFile == NULL || hFile->Read(data,1,length) != length) png_error(png_ptr, "Read Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PNGAPI user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||||
|
{
|
||||||
|
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
|
||||||
|
if (hFile == NULL || hFile->Write(data,1,length) != length) png_error(png_ptr, "Write Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PNGAPI user_flush_data(png_structp png_ptr)
|
||||||
|
{
|
||||||
|
CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
|
||||||
|
if (hFile == NULL || !hFile->Flush()) png_error(png_ptr, "Flush Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PNGAPI user_error_fn(png_structp png_ptr,png_const_charp error_msg)
|
||||||
|
{
|
||||||
|
strncpy((char*)png_ptr->error_ptr,error_msg,255);
|
||||||
|
longjmp(png_ptr->png_jmpbuf, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
1310
Raw2Bmp_MFC/include/ximapsd.cpp
Normal file
1310
Raw2Bmp_MFC/include/ximapsd.cpp
Normal file
File diff suppressed because it is too large
Load Diff
110
Raw2Bmp_MFC/include/ximapsd.h
Normal file
110
Raw2Bmp_MFC/include/ximapsd.h
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* File: ximapsd.h
|
||||||
|
* Purpose: PSD Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImagePSD (c) Dec/2010
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* libpsd (c) 2004-2007 Graphest Software
|
||||||
|
*
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaPSD_h)
|
||||||
|
#define __ximaPSD_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_PSD
|
||||||
|
|
||||||
|
#define CXIMAGE_USE_LIBPSD 1
|
||||||
|
|
||||||
|
#if CXIMAGE_USE_LIBPSD
|
||||||
|
extern "C" {
|
||||||
|
#include "../libpsd/libpsd.h"
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CxImagePSD: public CxImage
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImagePSD(): CxImage(CXIMAGE_FORMAT_PSD) {}
|
||||||
|
|
||||||
|
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PSD);}
|
||||||
|
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PSD);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
//#if CXIMAGE_SUPPORT_EXIF
|
||||||
|
// bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type);
|
||||||
|
//#endif //CXIMAGE_SUPPORT_EXIF
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
#if CXIMAGE_USE_LIBPSD
|
||||||
|
protected:
|
||||||
|
class CxFilePsd
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxFilePsd(CxFile* pFile,psd_context *context)
|
||||||
|
{
|
||||||
|
context->file = pFile;
|
||||||
|
|
||||||
|
psd_CxFile_ops.size_ = psd_file_size;
|
||||||
|
psd_CxFile_ops.seek_ = psd_file_seek;
|
||||||
|
psd_CxFile_ops.read_ = psd_file_read;
|
||||||
|
// psd_CxFile_ops.write_ = psd_file_write;
|
||||||
|
// psd_CxFile_ops.close_ = psd_file_close;
|
||||||
|
// psd_CxFile_ops.gets_ = psd_file_gets;
|
||||||
|
// psd_CxFile_ops.eof_ = psd_file_eof;
|
||||||
|
// psd_CxFile_ops.tell_ = psd_file_tell;
|
||||||
|
// psd_CxFile_ops.getc_ = psd_file_getc;
|
||||||
|
// psd_CxFile_ops.scanf_ = psd_file_scanf;
|
||||||
|
|
||||||
|
context->ops_ = &psd_CxFile_ops;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t psd_file_size(psd_file_obj *obj)
|
||||||
|
{ return ((CxFile*)obj)->Size(); }
|
||||||
|
|
||||||
|
static int32_t psd_file_seek(psd_file_obj *obj, int32_t offset, int32_t origin)
|
||||||
|
{ return ((CxFile*)obj)->Seek(offset,origin); }
|
||||||
|
|
||||||
|
static int32_t psd_file_read(psd_file_obj *obj, void *buf, int32_t size, int32_t cnt)
|
||||||
|
{ return ((CxFile*)obj)->Read(buf,size,cnt); }
|
||||||
|
|
||||||
|
// static int32_t psd_file_write(psd_file_obj *obj, void *buf, int32_t size, int32_t cnt)
|
||||||
|
// { return ((CxFile*)obj)->Write(buf,size,cnt); }
|
||||||
|
|
||||||
|
// static int32_t psd_file_close(psd_file_obj *obj)
|
||||||
|
// { return 1; /*((CxFile*)obj)->Close();*/ }
|
||||||
|
|
||||||
|
// static char* psd_file_gets(psd_file_obj *obj, char *string, int32_t n)
|
||||||
|
// { return ((CxFile*)obj)->GetS(string,n); }
|
||||||
|
|
||||||
|
// static int32_t psd_file_eof(psd_file_obj *obj)
|
||||||
|
// { return ((CxFile*)obj)->Eof(); }
|
||||||
|
|
||||||
|
// static long psd_file_tell(psd_file_obj *obj)
|
||||||
|
// { return ((CxFile*)obj)->Tell(); }
|
||||||
|
|
||||||
|
// static int32_t psd_file_getc(psd_file_obj *obj)
|
||||||
|
// { return ((CxFile*)obj)->GetC(); }
|
||||||
|
|
||||||
|
// static int32_t psd_file_scanf(psd_file_obj *obj,const char *format, void* output)
|
||||||
|
// { return ((CxFile*)obj)->Scanf(format, output); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
psd_file_ops psd_CxFile_ops;
|
||||||
|
};
|
||||||
|
#endif //CXIMAGE_USE_LIBPSD
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
333
Raw2Bmp_MFC/include/ximaraw.cpp
Normal file
333
Raw2Bmp_MFC/include/ximaraw.cpp
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaraw.cpp
|
||||||
|
* Purpose: Platform Independent RAW Image Class Loader
|
||||||
|
* 16/Dec/2007 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*
|
||||||
|
* CxImageRAW (c) May/2006 pdw63
|
||||||
|
*
|
||||||
|
* based on dcraw.c -- Dave Coffin's raw photo decoder
|
||||||
|
* Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximaraw.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageRAW::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile==NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DCRAW dcr;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
// initialization
|
||||||
|
dcr_init_dcraw(&dcr);
|
||||||
|
|
||||||
|
dcr.opt.user_qual = GetCodecOption(CXIMAGE_FORMAT_RAW) & 0x03;
|
||||||
|
|
||||||
|
// setup variables for debugging
|
||||||
|
char szClass[] = "CxImageRAW";
|
||||||
|
dcr.ifname = szClass;
|
||||||
|
dcr.sz_error = info.szLastError;
|
||||||
|
|
||||||
|
// setup library options, see dcr_print_manual for the available switches
|
||||||
|
// call dcr_parse_command_line_options(&dcr,0,0,0) to set default options
|
||||||
|
// if (dcr_parse_command_line_options(&dcr,argc,argv,&arg))
|
||||||
|
if (dcr_parse_command_line_options(&dcr,0,0,0)){
|
||||||
|
cx_throw("CxImageRAW: unknown option");
|
||||||
|
}
|
||||||
|
|
||||||
|
// set return point for error handling
|
||||||
|
if (setjmp (dcr.failure)) {
|
||||||
|
cx_throw("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// install file manager
|
||||||
|
CxFileRaw src(hFile,&dcr);
|
||||||
|
|
||||||
|
// check file header
|
||||||
|
dcr_identify(&dcr);
|
||||||
|
|
||||||
|
if(!dcr.is_raw){
|
||||||
|
cx_throw("CxImageRAW: not a raw image");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dcr.load_raw == NULL) {
|
||||||
|
cx_throw("CxImageRAW: missing raw decoder");
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify special case
|
||||||
|
if (dcr.load_raw == dcr_kodak_ycbcr_load_raw) {
|
||||||
|
dcr.height += dcr.height & 1;
|
||||||
|
dcr.width += dcr.width & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = dcr.width;
|
||||||
|
head.biHeight= dcr.height;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_RAW;
|
||||||
|
cx_throw("output dimensions returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
// shrinked decoding available and requested?
|
||||||
|
dcr.shrink = dcr.filters && (dcr.opt.half_size || dcr.opt.threshold || dcr.opt.aber[0] != 1 || dcr.opt.aber[2] != 1);
|
||||||
|
dcr.iheight = (dcr.height + dcr.shrink) >> dcr.shrink;
|
||||||
|
dcr.iwidth = (dcr.width + dcr.shrink) >> dcr.shrink;
|
||||||
|
|
||||||
|
// install custom camera matrix
|
||||||
|
if (dcr.opt.use_camera_matrix && dcr.cmatrix[0][0] > 0.25) {
|
||||||
|
memcpy (dcr.rgb_cam, dcr.cmatrix, sizeof dcr.cmatrix);
|
||||||
|
dcr.raw_color = 0;
|
||||||
|
} else {
|
||||||
|
dcr.opt.use_camera_wb = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate memory for the image
|
||||||
|
dcr.image = (ushort (*)[4]) calloc (dcr.iheight*dcr.iwidth, sizeof *dcr.image);
|
||||||
|
dcr_merror (&dcr, dcr.image, szClass);
|
||||||
|
|
||||||
|
if (dcr.meta_length) {
|
||||||
|
dcr.meta_data = (char *) malloc (dcr.meta_length);
|
||||||
|
dcr_merror (&dcr, dcr.meta_data, szClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start image decoder
|
||||||
|
hFile->Seek(dcr.data_offset, SEEK_SET);
|
||||||
|
(*dcr.load_raw)(&dcr);
|
||||||
|
|
||||||
|
// post processing
|
||||||
|
if (dcr.zero_is_bad) dcr_remove_zeroes(&dcr);
|
||||||
|
|
||||||
|
dcr_bad_pixels(&dcr,dcr.opt.bpfile);
|
||||||
|
|
||||||
|
if (dcr.opt.dark_frame) dcr_subtract (&dcr,dcr.opt.dark_frame);
|
||||||
|
|
||||||
|
dcr.quality = 2 + !dcr.fuji_width;
|
||||||
|
|
||||||
|
if (dcr.opt.user_qual >= 0) dcr.quality = dcr.opt.user_qual;
|
||||||
|
|
||||||
|
if (dcr.opt.user_black >= 0) dcr.black = dcr.opt.user_black;
|
||||||
|
|
||||||
|
if (dcr.opt.user_sat >= 0) dcr.maximum = dcr.opt.user_sat;
|
||||||
|
|
||||||
|
#ifdef COLORCHECK
|
||||||
|
dcr_colorcheck(&dcr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RESTRICTED
|
||||||
|
if (dcr.is_foveon && !dcr.opt.document_mode) dcr_foveon_interpolate(&dcr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!dcr.is_foveon && dcr.opt.document_mode < 2) dcr_scale_colors(&dcr);
|
||||||
|
|
||||||
|
// pixel interpolation and filters
|
||||||
|
dcr_pre_interpolate(&dcr);
|
||||||
|
|
||||||
|
if (dcr.filters && !dcr.opt.document_mode) {
|
||||||
|
if (dcr.quality == 0)
|
||||||
|
dcr_lin_interpolate(&dcr);
|
||||||
|
else if (dcr.quality == 1 || dcr.colors > 3)
|
||||||
|
dcr_vng_interpolate(&dcr);
|
||||||
|
else if (dcr.quality == 2)
|
||||||
|
dcr_ppg_interpolate(&dcr);
|
||||||
|
else
|
||||||
|
dcr_ahd_interpolate(&dcr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dcr.mix_green) {
|
||||||
|
int32_t i;
|
||||||
|
for (dcr.colors=3, i=0; i < dcr.height*dcr.width; i++) {
|
||||||
|
dcr.image[i][1] = (dcr.image[i][1] + dcr.image[i][3]) >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dcr.is_foveon && dcr.colors == 3) dcr_median_filter(&dcr);
|
||||||
|
|
||||||
|
if (!dcr.is_foveon && dcr.opt.highlight == 2) dcr_blend_highlights(&dcr);
|
||||||
|
|
||||||
|
if (!dcr.is_foveon && dcr.opt.highlight > 2) dcr_recover_highlights(&dcr);
|
||||||
|
|
||||||
|
if (dcr.opt.use_fuji_rotate) dcr_fuji_rotate(&dcr);
|
||||||
|
|
||||||
|
#ifndef NO_LCMS
|
||||||
|
if (dcr.opt.cam_profile) dcr_apply_profile (dcr.opt.cam_profile, dcr.opt.out_profile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// final conversion
|
||||||
|
dcr_convert_to_rgb(&dcr);
|
||||||
|
|
||||||
|
if (dcr.opt.use_fuji_rotate) dcr_stretch(&dcr);
|
||||||
|
|
||||||
|
dcr.iheight = dcr.height;
|
||||||
|
dcr.iwidth = dcr.width;
|
||||||
|
if (dcr.flip & 4) SWAP(dcr.height,dcr.width);
|
||||||
|
|
||||||
|
// ready to transfer data from dcr.image
|
||||||
|
if (!Create(dcr.width,dcr.height,24,CXIMAGE_FORMAT_RAW)){
|
||||||
|
cx_throw("");
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar *ppm = (uchar *) calloc (dcr.width, dcr.colors*dcr.opt.output_bps/8);
|
||||||
|
ushort *ppm2 = (ushort *) ppm;
|
||||||
|
dcr_merror (&dcr, ppm, szClass);
|
||||||
|
|
||||||
|
uchar lut[0x10000];
|
||||||
|
if (dcr.opt.output_bps == 8) dcr_gamma_lut (&dcr, lut);
|
||||||
|
|
||||||
|
int32_t c, row, col, soff, rstep, cstep;
|
||||||
|
soff = dcr_flip_index (&dcr, 0, 0);
|
||||||
|
cstep = dcr_flip_index (&dcr, 0, 1) - soff;
|
||||||
|
rstep = dcr_flip_index (&dcr, 1, 0) - dcr_flip_index (&dcr, 0, dcr.width);
|
||||||
|
for (row=0; row < dcr.height; row++, soff += rstep) {
|
||||||
|
for (col=0; col < dcr.width; col++, soff += cstep) {
|
||||||
|
if (dcr.opt.output_bps == 8)
|
||||||
|
for (c=0; c < dcr.colors; c++) ppm [col*dcr.colors+c] = lut[dcr.image[soff][c]];
|
||||||
|
else
|
||||||
|
for (c=0; c < dcr.colors; c++) ppm2[col*dcr.colors+c] = dcr.image[soff][c];
|
||||||
|
}
|
||||||
|
if (dcr.opt.output_bps == 16 && !dcr.opt.output_tiff && htons(0x55aa) != 0x55aa)
|
||||||
|
#if defined(_LINUX) || defined(__APPLE__)
|
||||||
|
swab ((char*)ppm2, (char*)ppm2, dcr.width*dcr.colors*2);
|
||||||
|
#else
|
||||||
|
_swab ((char*)ppm2, (char*)ppm2, dcr.width*dcr.colors*2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t size = dcr.width * (dcr.colors*dcr.opt.output_bps/8);
|
||||||
|
RGBtoBGR(ppm,size);
|
||||||
|
memcpy(GetBits(dcr.height - 1 - row), ppm, min(size,GetEffWidth()));
|
||||||
|
}
|
||||||
|
free (ppm);
|
||||||
|
|
||||||
|
|
||||||
|
dcr_cleanup_dcraw(&dcr);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
|
||||||
|
dcr_cleanup_dcraw(&dcr);
|
||||||
|
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_RAW) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* that's it */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_EXIF
|
||||||
|
bool CxImageRAW::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
|
||||||
|
{
|
||||||
|
DCRAW dcr;
|
||||||
|
|
||||||
|
CxIOFile file;
|
||||||
|
if (!file.Open(filename, _T("rb")))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
// initialization
|
||||||
|
dcr_init_dcraw(&dcr);
|
||||||
|
|
||||||
|
dcr.opt.user_qual = GetCodecOption(CXIMAGE_FORMAT_RAW) & 0x03;
|
||||||
|
|
||||||
|
// setup variables for debugging
|
||||||
|
char szClass[] = "CxImageRAW";
|
||||||
|
dcr.ifname = szClass;
|
||||||
|
dcr.sz_error = info.szLastError;
|
||||||
|
|
||||||
|
// setup library options, see dcr_print_manual for the available switches
|
||||||
|
// call dcr_parse_command_line_options(&dcr,0,0,0) to set default options
|
||||||
|
// if (dcr_parse_command_line_options(&dcr,argc,argv,&arg))
|
||||||
|
if (dcr_parse_command_line_options(&dcr,0,0,0)){
|
||||||
|
cx_throw("CxImageRAW: unknown option");
|
||||||
|
}
|
||||||
|
|
||||||
|
// set return point for error handling
|
||||||
|
if (setjmp (dcr.failure)) {
|
||||||
|
cx_throw("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// install file manager
|
||||||
|
CxFileRaw src(&file,&dcr);
|
||||||
|
|
||||||
|
// check file header
|
||||||
|
dcr_identify(&dcr);
|
||||||
|
|
||||||
|
if(!dcr.is_raw){
|
||||||
|
cx_throw("CxImageRAW: not a raw image");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dcr.load_raw == NULL) {
|
||||||
|
cx_throw("CxImageRAW: missing raw decoder");
|
||||||
|
}
|
||||||
|
|
||||||
|
// THUMB.
|
||||||
|
if (dcr.thumb_offset != 0)
|
||||||
|
{
|
||||||
|
FILE* file = _tfopen(outname, _T("wb"));
|
||||||
|
DCRAW* p = &dcr;
|
||||||
|
dcr_fseek(dcr.obj_, dcr.thumb_offset, SEEK_SET);
|
||||||
|
dcr.write_thumb(&dcr, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// Read in the thumbnail to resize and rotate.
|
||||||
|
CxImage image(outname, CXIMAGE_FORMAT_UNKNOWN);
|
||||||
|
if (image.IsValid())
|
||||||
|
{
|
||||||
|
#if CXIMAGE_SUPPORT_TRANSFORMATION
|
||||||
|
// Resizing.
|
||||||
|
if (image.GetWidth() > 256 || image.GetHeight() > 256)
|
||||||
|
{
|
||||||
|
float amount = 256.0f / max(image.GetWidth(), image.GetHeight());
|
||||||
|
image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0);
|
||||||
|
}
|
||||||
|
// Rotation.
|
||||||
|
if (p->flip != 0)
|
||||||
|
image.RotateExif(p->flip);
|
||||||
|
#endif
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE && CXIMAGE_SUPPORT_JPG
|
||||||
|
return image.Save(outname, CXIMAGE_FORMAT_JPG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cx_throw("No thumbnail!");
|
||||||
|
}
|
||||||
|
|
||||||
|
dcr_cleanup_dcraw(&dcr);
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
|
||||||
|
dcr_cleanup_dcraw(&dcr);
|
||||||
|
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_RAW) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* that's it */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif //CXIMAGE_SUPPORT_EXIF
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageRAW::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
strcpy(info.szLastError, "Save RAW not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_RAW
|
||||||
|
|
||||||
112
Raw2Bmp_MFC/include/ximaraw.h
Normal file
112
Raw2Bmp_MFC/include/ximaraw.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaraw.h
|
||||||
|
* Purpose: RAW Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageRAW (c) May/2006 pdw63
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
* Special thanks to David Coffin for dcraw without which this class would not exist
|
||||||
|
*
|
||||||
|
* libdcr (c) Dec/2007 Davide Pizzolato - www.xdp.it
|
||||||
|
*
|
||||||
|
* based on dcraw.c -- Dave Coffin's raw photo decoder
|
||||||
|
* Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaRAW_h)
|
||||||
|
#define __ximaRAW_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_RAW
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "../raw/libdcr.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
class CxImageRAW: public CxImage
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImageRAW(): CxImage(CXIMAGE_FORMAT_RAW) {}
|
||||||
|
|
||||||
|
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
|
||||||
|
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_EXIF
|
||||||
|
bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type);
|
||||||
|
#endif //CXIMAGE_SUPPORT_EXIF
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
enum CODEC_OPTION
|
||||||
|
{
|
||||||
|
DECODE_QUALITY_LIN = 0x00,
|
||||||
|
DECODE_QUALITY_VNG = 0x01,
|
||||||
|
DECODE_QUALITY_PPG = 0x02,
|
||||||
|
DECODE_QUALITY_AHD = 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
class CxFileRaw
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxFileRaw(CxFile* pFile,DCRAW *stream)
|
||||||
|
{
|
||||||
|
stream->obj_ = pFile;
|
||||||
|
|
||||||
|
ras_stream_CxFile.read_ = raw_sfile_read;
|
||||||
|
ras_stream_CxFile.write_ = raw_sfile_write;
|
||||||
|
ras_stream_CxFile.seek_ = raw_sfile_seek;
|
||||||
|
ras_stream_CxFile.close_ = raw_sfile_close;
|
||||||
|
ras_stream_CxFile.gets_ = raw_sfile_gets;
|
||||||
|
ras_stream_CxFile.eof_ = raw_sfile_eof;
|
||||||
|
ras_stream_CxFile.tell_ = raw_sfile_tell;
|
||||||
|
ras_stream_CxFile.getc_ = raw_sfile_getc;
|
||||||
|
ras_stream_CxFile.scanf_ = raw_sfile_scanf;
|
||||||
|
|
||||||
|
stream->ops_ = &ras_stream_CxFile;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t raw_sfile_read(dcr_stream_obj *obj, void *buf, int32_t size, int32_t cnt)
|
||||||
|
{ return ((CxFile*)obj)->Read(buf,size,cnt); }
|
||||||
|
|
||||||
|
static int32_t raw_sfile_write(dcr_stream_obj *obj, void *buf, int32_t size, int32_t cnt)
|
||||||
|
{ return ((CxFile*)obj)->Write(buf,size,cnt); }
|
||||||
|
|
||||||
|
static long raw_sfile_seek(dcr_stream_obj *obj, long offset, int32_t origin)
|
||||||
|
{ return ((CxFile*)obj)->Seek(offset,origin); }
|
||||||
|
|
||||||
|
static int32_t raw_sfile_close(dcr_stream_obj *obj)
|
||||||
|
{ return 1; /*((CxFile*)obj)->Close();*/ }
|
||||||
|
|
||||||
|
static char* raw_sfile_gets(dcr_stream_obj *obj, char *string, int32_t n)
|
||||||
|
{ return ((CxFile*)obj)->GetS(string,n); }
|
||||||
|
|
||||||
|
static int32_t raw_sfile_eof(dcr_stream_obj *obj)
|
||||||
|
{ return ((CxFile*)obj)->Eof(); }
|
||||||
|
|
||||||
|
static long raw_sfile_tell(dcr_stream_obj *obj)
|
||||||
|
{ return ((CxFile*)obj)->Tell(); }
|
||||||
|
|
||||||
|
static int32_t raw_sfile_getc(dcr_stream_obj *obj)
|
||||||
|
{ return ((CxFile*)obj)->GetC(); }
|
||||||
|
|
||||||
|
static int32_t raw_sfile_scanf(dcr_stream_obj *obj,const char *format, void* output)
|
||||||
|
{ return ((CxFile*)obj)->Scanf(format, output); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
dcr_stream_ops ras_stream_CxFile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
698
Raw2Bmp_MFC/include/ximasel.cpp
Normal file
698
Raw2Bmp_MFC/include/ximasel.cpp
Normal file
@@ -0,0 +1,698 @@
|
|||||||
|
// xImaSel.cpp : Selection functions
|
||||||
|
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the image has a valid selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionIsValid()
|
||||||
|
{
|
||||||
|
return pSelection!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_SELECTION
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Gets the smallest rectangle that contains the selection
|
||||||
|
*/
|
||||||
|
void CxImage::SelectionGetBox(RECT& r)
|
||||||
|
{
|
||||||
|
memcpy(&r,&info.rSelectionBox,sizeof(RECT));
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Empties the selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionClear(uint8_t level)
|
||||||
|
{
|
||||||
|
if (pSelection){
|
||||||
|
if (level==0){
|
||||||
|
memset(pSelection,0,head.biWidth * head.biHeight);
|
||||||
|
info.rSelectionBox.left = head.biWidth;
|
||||||
|
info.rSelectionBox.bottom = head.biHeight;
|
||||||
|
info.rSelectionBox.right = info.rSelectionBox.top = 0;
|
||||||
|
} else {
|
||||||
|
memset(pSelection,level,head.biWidth * head.biHeight);
|
||||||
|
info.rSelectionBox.right = head.biWidth;
|
||||||
|
info.rSelectionBox.top = head.biHeight;
|
||||||
|
info.rSelectionBox.left = info.rSelectionBox.bottom = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Allocates an empty selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionCreate()
|
||||||
|
{
|
||||||
|
SelectionDelete();
|
||||||
|
pSelection = (uint8_t*)calloc(head.biWidth * head.biHeight, 1);
|
||||||
|
return (pSelection!=0);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Deallocates the selction.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionDelete()
|
||||||
|
{
|
||||||
|
if (pSelection){
|
||||||
|
free(pSelection);
|
||||||
|
pSelection=NULL;
|
||||||
|
}
|
||||||
|
info.rSelectionBox.left = head.biWidth;
|
||||||
|
info.rSelectionBox.bottom = head.biHeight;
|
||||||
|
info.rSelectionBox.right = info.rSelectionBox.top = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the coordinates are inside the selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionIsInside(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
if (IsInside(x,y)){
|
||||||
|
if (pSelection==NULL) return true;
|
||||||
|
return pSelection[x+y*head.biWidth]!=0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Checks if the coordinates are inside the selection.
|
||||||
|
* "blind" version assumes that (x,y) is inside to the image.
|
||||||
|
*/
|
||||||
|
bool CxImage::BlindSelectionIsInside(int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (!IsInside(x,y))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
if (pSelection==NULL) return true;
|
||||||
|
return pSelection[x+y*head.biWidth]!=0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Adds a rectangle to the existing selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionAddRect(RECT r, uint8_t level)
|
||||||
|
{
|
||||||
|
if (pSelection==NULL) SelectionCreate();
|
||||||
|
if (pSelection==NULL) return false;
|
||||||
|
|
||||||
|
RECT r2;
|
||||||
|
if (r.left<r.right) {r2.left=r.left; r2.right=r.right; } else {r2.left=r.right ; r2.right=r.left; }
|
||||||
|
if (r.bottom<r.top) {r2.bottom=r.bottom; r2.top=r.top; } else {r2.bottom=r.top ; r2.top=r.bottom; }
|
||||||
|
|
||||||
|
if (info.rSelectionBox.top <= r2.top) info.rSelectionBox.top = max(0L,min(head.biHeight,r2.top+1));
|
||||||
|
if (info.rSelectionBox.left > r2.left) info.rSelectionBox.left = max(0L,min(head.biWidth,r2.left));
|
||||||
|
if (info.rSelectionBox.right <= r2.right) info.rSelectionBox.right = max(0L,min(head.biWidth,r2.right+1));
|
||||||
|
if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0L,min(head.biHeight,r2.bottom));
|
||||||
|
|
||||||
|
int32_t ymin = max(0L,min(head.biHeight,r2.bottom));
|
||||||
|
int32_t ymax = max(0L,min(head.biHeight,r2.top+1));
|
||||||
|
int32_t xmin = max(0L,min(head.biWidth,r2.left));
|
||||||
|
int32_t xmax = max(0L,min(head.biWidth,r2.right+1));
|
||||||
|
|
||||||
|
for (int32_t y=ymin; y<ymax; y++)
|
||||||
|
memset(pSelection + xmin + y * head.biWidth, level, xmax-xmin);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Adds an ellipse to the existing selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionAddEllipse(RECT r, uint8_t level)
|
||||||
|
{
|
||||||
|
if (pSelection==NULL) SelectionCreate();
|
||||||
|
if (pSelection==NULL) return false;
|
||||||
|
|
||||||
|
int32_t xradius = abs(r.right - r.left)/2;
|
||||||
|
int32_t yradius = abs(r.top - r.bottom)/2;
|
||||||
|
if (xradius==0 || yradius==0) return false;
|
||||||
|
|
||||||
|
int32_t xcenter = (r.right + r.left)/2;
|
||||||
|
int32_t ycenter = (r.top + r.bottom)/2;
|
||||||
|
|
||||||
|
if (info.rSelectionBox.left > (xcenter - xradius)) info.rSelectionBox.left = max(0L,min(head.biWidth,(xcenter - xradius)));
|
||||||
|
if (info.rSelectionBox.right <= (xcenter + xradius)) info.rSelectionBox.right = max(0L,min(head.biWidth,(xcenter + xradius + 1)));
|
||||||
|
if (info.rSelectionBox.bottom > (ycenter - yradius)) info.rSelectionBox.bottom = max(0L,min(head.biHeight,(ycenter - yradius)));
|
||||||
|
if (info.rSelectionBox.top <= (ycenter + yradius)) info.rSelectionBox.top = max(0L,min(head.biHeight,(ycenter + yradius + 1)));
|
||||||
|
|
||||||
|
int32_t xmin = max(0L,min(head.biWidth,xcenter - xradius));
|
||||||
|
int32_t xmax = max(0L,min(head.biWidth,xcenter + xradius + 1));
|
||||||
|
int32_t ymin = max(0L,min(head.biHeight,ycenter - yradius));
|
||||||
|
int32_t ymax = max(0L,min(head.biHeight,ycenter + yradius + 1));
|
||||||
|
|
||||||
|
int32_t y,yo;
|
||||||
|
for (y=ymin; y<min(ycenter,ymax); y++){
|
||||||
|
for (int32_t x=xmin; x<xmax; x++){
|
||||||
|
yo = (int32_t)(ycenter - yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
|
||||||
|
if (yo<y) pSelection[x + y * head.biWidth] = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (y=ycenter; y<ymax; y++){
|
||||||
|
for (int32_t x=xmin; x<xmax; x++){
|
||||||
|
yo = (int32_t)(ycenter + yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
|
||||||
|
if (yo>y) pSelection[x + y * head.biWidth] = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Inverts the selection.
|
||||||
|
* Note: the SelectionBox is set to "full image", call SelectionGetBox before (if necessary)
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionInvert()
|
||||||
|
{
|
||||||
|
if (pSelection) {
|
||||||
|
uint8_t *iSrc=pSelection;
|
||||||
|
int32_t n=head.biHeight*head.biWidth;
|
||||||
|
for(int32_t i=0; i < n; i++){
|
||||||
|
*iSrc=(uint8_t)~(*(iSrc));
|
||||||
|
iSrc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectionRebuildBox();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Imports an existing region from another image with the same width and height.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionCopy(CxImage &from)
|
||||||
|
{
|
||||||
|
if (from.pSelection == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
|
||||||
|
if (pSelection==NULL) pSelection = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
if (pSelection==NULL) return false;
|
||||||
|
memcpy(pSelection,from.pSelection,head.biWidth * head.biHeight);
|
||||||
|
memcpy(&info.rSelectionBox,&from.info.rSelectionBox,sizeof(RECT));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Adds a polygonal region to the existing selection. points points to an array of POINT structures.
|
||||||
|
* Each structure specifies the x-coordinate and y-coordinate of one vertex of the polygon.
|
||||||
|
* npoints specifies the number of POINT structures in the array pointed to by points.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionAddPolygon(POINT *points, int32_t npoints, uint8_t level)
|
||||||
|
{
|
||||||
|
if (points==NULL || npoints<3) return false;
|
||||||
|
|
||||||
|
if (pSelection==NULL) SelectionCreate();
|
||||||
|
if (pSelection==NULL) return false;
|
||||||
|
|
||||||
|
uint8_t* plocal = (uint8_t*)calloc(head.biWidth*head.biHeight, 1);
|
||||||
|
RECT localbox = {head.biWidth,0,0,head.biHeight};
|
||||||
|
|
||||||
|
int32_t x,y,i=0;
|
||||||
|
POINT *current;
|
||||||
|
POINT *next = NULL;
|
||||||
|
POINT *start = NULL;
|
||||||
|
//trace contour
|
||||||
|
while (i < npoints){
|
||||||
|
current = &points[i];
|
||||||
|
if (current->x!=-1){
|
||||||
|
if (i==0 || (i>0 && points[i-1].x==-1)) start = &points[i];
|
||||||
|
|
||||||
|
if ((i+1)==npoints || points[i+1].x==-1)
|
||||||
|
next = start;
|
||||||
|
else
|
||||||
|
next = &points[i+1];
|
||||||
|
|
||||||
|
float beta;
|
||||||
|
if (current->x != next->x){
|
||||||
|
beta = (float)(next->y - current->y)/(float)(next->x - current->x);
|
||||||
|
if (current->x < next->x){
|
||||||
|
for (x=current->x; x<=next->x; x++){
|
||||||
|
y = (int32_t)(current->y + (x - current->x) * beta);
|
||||||
|
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (x=current->x; x>=next->x; x--){
|
||||||
|
y = (int32_t)(current->y + (x - current->x) * beta);
|
||||||
|
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current->y != next->y){
|
||||||
|
beta = (float)(next->x - current->x)/(float)(next->y - current->y);
|
||||||
|
if (current->y < next->y){
|
||||||
|
for (y=current->y; y<=next->y; y++){
|
||||||
|
x = (int32_t)(current->x + (y - current->y) * beta);
|
||||||
|
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (y=current->y; y>=next->y; y--){
|
||||||
|
x = (int32_t)(current->x + (y - current->y) * beta);
|
||||||
|
if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT r2;
|
||||||
|
if (current->x < next->x) {r2.left=current->x; r2.right=next->x; } else {r2.left=next->x ; r2.right=current->x; }
|
||||||
|
if (current->y < next->y) {r2.bottom=current->y; r2.top=next->y; } else {r2.bottom=next->y ; r2.top=current->y; }
|
||||||
|
if (localbox.top < r2.top) localbox.top = max(0L,min(head.biHeight-1,r2.top+1));
|
||||||
|
if (localbox.left > r2.left) localbox.left = max(0L,min(head.biWidth-1,r2.left-1));
|
||||||
|
if (localbox.right < r2.right) localbox.right = max(0L,min(head.biWidth-1,r2.right+1));
|
||||||
|
if (localbox.bottom > r2.bottom) localbox.bottom = max(0L,min(head.biHeight-1,r2.bottom-1));
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//fill the outer region
|
||||||
|
int32_t npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom);
|
||||||
|
POINT* pix = (POINT*)calloc(npix,sizeof(POINT));
|
||||||
|
uint8_t back=0, mark=1;
|
||||||
|
int32_t fx, fy, fxx, fyy, first, last;
|
||||||
|
int32_t xmin = 0;
|
||||||
|
int32_t xmax = 0;
|
||||||
|
int32_t ymin = 0;
|
||||||
|
int32_t ymax = 0;
|
||||||
|
|
||||||
|
for (int32_t side=0; side<4; side++){
|
||||||
|
switch(side){
|
||||||
|
case 0:
|
||||||
|
xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.bottom+1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
xmin=localbox.right; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.top+1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.top; ymax=localbox.top+1;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
xmin=localbox.left; xmax=localbox.left+1; ymin=localbox.bottom; ymax=localbox.top+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//fill from the border points
|
||||||
|
for(y=ymin;y<ymax;y++){
|
||||||
|
for(x=xmin;x<xmax;x++){
|
||||||
|
if (plocal[x+y*head.biWidth]==0){
|
||||||
|
// Subject: FLOOD FILL ROUTINE Date: 12-23-97 (00:57)
|
||||||
|
// Author: Petter Holmberg Code: QB, QBasic, PDS
|
||||||
|
// Origin: petter.holmberg@usa.net Packet: GRAPHICS.ABC
|
||||||
|
first=0;
|
||||||
|
last=1;
|
||||||
|
while(first!=last){
|
||||||
|
fx = pix[first].x;
|
||||||
|
fy = pix[first].y;
|
||||||
|
fxx = fx + x;
|
||||||
|
fyy = fy + y;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if ((plocal[fxx + fyy*head.biWidth] == back) &&
|
||||||
|
fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
|
||||||
|
{
|
||||||
|
plocal[fxx + fyy*head.biWidth] = mark;
|
||||||
|
if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
|
||||||
|
pix[last].x = fx;
|
||||||
|
pix[last].y = fy - 1;
|
||||||
|
last++;
|
||||||
|
if (last == npix) last = 0;
|
||||||
|
}
|
||||||
|
if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
|
||||||
|
pix[last].x = fx;
|
||||||
|
pix[last].y = fy + 1;
|
||||||
|
last++;
|
||||||
|
if (last == npix) last = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fx++;
|
||||||
|
fxx++;
|
||||||
|
};
|
||||||
|
|
||||||
|
fx = pix[first].x - 1;
|
||||||
|
fy = pix[first].y;
|
||||||
|
fxx = fx + x;
|
||||||
|
fyy = fy + y;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
if ((plocal[fxx + fyy*head.biWidth] == back) &&
|
||||||
|
fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
|
||||||
|
{
|
||||||
|
plocal[fxx + (y + fy)*head.biWidth] = mark;
|
||||||
|
if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
|
||||||
|
pix[last].x = fx;
|
||||||
|
pix[last].y = fy - 1;
|
||||||
|
last++;
|
||||||
|
if (last == npix) last = 0;
|
||||||
|
}
|
||||||
|
if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
|
||||||
|
pix[last].x = fx;
|
||||||
|
pix[last].y = fy + 1;
|
||||||
|
last++;
|
||||||
|
if (last == npix) last = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fx--;
|
||||||
|
fxx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
first++;
|
||||||
|
if (first == npix) first = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//transfer the region
|
||||||
|
int32_t yoffset;
|
||||||
|
for (y=localbox.bottom; y<=localbox.top; y++){
|
||||||
|
yoffset = y * head.biWidth;
|
||||||
|
for (x=localbox.left; x<=localbox.right; x++)
|
||||||
|
if (plocal[x + yoffset]!=1) pSelection[x + yoffset]=level;
|
||||||
|
}
|
||||||
|
if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = min(head.biHeight,localbox.top + 1);
|
||||||
|
if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = min(head.biWidth,localbox.left);
|
||||||
|
if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = min(head.biWidth,localbox.right + 1);
|
||||||
|
if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = min(head.biHeight,localbox.bottom);
|
||||||
|
|
||||||
|
free(plocal);
|
||||||
|
free(pix);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Adds to the selection all the pixels matching the specified color.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionAddColor(RGBQUAD c, uint8_t level)
|
||||||
|
{
|
||||||
|
if (pSelection==NULL) SelectionCreate();
|
||||||
|
if (pSelection==NULL) return false;
|
||||||
|
|
||||||
|
RECT localbox = {head.biWidth,0,0,head.biHeight};
|
||||||
|
|
||||||
|
for (int32_t y = 0; y < head.biHeight; y++){
|
||||||
|
for (int32_t x = 0; x < head.biWidth; x++){
|
||||||
|
RGBQUAD color = BlindGetPixelColor(x, y);
|
||||||
|
if (color.rgbRed == c.rgbRed &&
|
||||||
|
color.rgbGreen == c.rgbGreen &&
|
||||||
|
color.rgbBlue == c.rgbBlue)
|
||||||
|
{
|
||||||
|
pSelection[x + y * head.biWidth] = level;
|
||||||
|
|
||||||
|
if (localbox.top < y) localbox.top = y;
|
||||||
|
if (localbox.left > x) localbox.left = x;
|
||||||
|
if (localbox.right < x) localbox.right = x;
|
||||||
|
if (localbox.bottom > y) localbox.bottom = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = localbox.top + 1;
|
||||||
|
if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
|
||||||
|
if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = localbox.right + 1;
|
||||||
|
if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Adds a single pixel to the existing selection.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionAddPixel(int32_t x, int32_t y, uint8_t level)
|
||||||
|
{
|
||||||
|
if (pSelection==NULL) SelectionCreate();
|
||||||
|
if (pSelection==NULL) return false;
|
||||||
|
|
||||||
|
if (IsInside(x,y)) {
|
||||||
|
pSelection[x + y * head.biWidth] = level; // set the correct mask bit
|
||||||
|
|
||||||
|
if (info.rSelectionBox.top <= y) info.rSelectionBox.top = y+1;
|
||||||
|
if (info.rSelectionBox.left > x) info.rSelectionBox.left = x;
|
||||||
|
if (info.rSelectionBox.right <= x) info.rSelectionBox.right = x+1;
|
||||||
|
if (info.rSelectionBox.bottom > y) info.rSelectionBox.bottom = y;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Exports the selection channel in a 8bpp grayscale image.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionSplit(CxImage *dest)
|
||||||
|
{
|
||||||
|
if (!pSelection || !dest) return false;
|
||||||
|
|
||||||
|
CxImage tmp(head.biWidth,head.biHeight,8);
|
||||||
|
if (!tmp.IsValid()){
|
||||||
|
strcpy(info.szLastError,tmp.GetLastError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32_t y=0; y<head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x<head.biWidth; x++){
|
||||||
|
tmp.BlindSetPixelIndex(x,y,pSelection[x+y*head.biWidth]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.SetGrayPalette();
|
||||||
|
dest->Transfer(tmp);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Creates the selection channel from a gray scale image.
|
||||||
|
* black = unselected
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionSet(CxImage &from)
|
||||||
|
{
|
||||||
|
if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight){
|
||||||
|
strcpy(info.szLastError,"CxImage::SelectionSet: wrong width or height, or image is not gray scale");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSelection==NULL) pSelection = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
|
||||||
|
uint8_t* src = from.info.pImage;
|
||||||
|
uint8_t* dst = pSelection;
|
||||||
|
if (src==NULL || dst==NULL){
|
||||||
|
strcpy(info.szLastError,"CxImage::SelectionSet: null pointer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t y=0; y<head.biHeight; y++){
|
||||||
|
memcpy(dst,src,head.biWidth);
|
||||||
|
dst += head.biWidth;
|
||||||
|
src += from.info.dwEffWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectionRebuildBox();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Sets the Selection level for a single pixel
|
||||||
|
* internal use only: doesn't set SelectionBox. Use SelectionAddPixel
|
||||||
|
*/
|
||||||
|
void CxImage::SelectionSet(const int32_t x,const int32_t y,const uint8_t level)
|
||||||
|
{
|
||||||
|
if (pSelection && IsInside(x,y)) pSelection[x+y*head.biWidth]=level;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Gets the Selection level for a single pixel
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::SelectionGet(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
if (pSelection && IsInside(x,y)) return pSelection[x+y*head.biWidth];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Rebuilds the SelectionBox
|
||||||
|
*/
|
||||||
|
void CxImage::SelectionRebuildBox()
|
||||||
|
{
|
||||||
|
info.rSelectionBox.left = head.biWidth;
|
||||||
|
info.rSelectionBox.bottom = head.biHeight;
|
||||||
|
info.rSelectionBox.right = info.rSelectionBox.top = 0;
|
||||||
|
|
||||||
|
if (!pSelection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32_t x,y;
|
||||||
|
|
||||||
|
for (y=0; y<head.biHeight; y++){
|
||||||
|
for (x=0; x<info.rSelectionBox.left; x++){
|
||||||
|
if (pSelection[x+y*head.biWidth]){
|
||||||
|
info.rSelectionBox.left = x;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y=0; y<head.biHeight; y++){
|
||||||
|
for (x=head.biWidth-1; x>=info.rSelectionBox.right; x--){
|
||||||
|
if (pSelection[x+y*head.biWidth]){
|
||||||
|
info.rSelectionBox.right = x+1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x=0; x<head.biWidth; x++){
|
||||||
|
for (y=0; y<info.rSelectionBox.bottom; y++){
|
||||||
|
if (pSelection[x+y*head.biWidth]){
|
||||||
|
info.rSelectionBox.bottom = y;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x=0; x<head.biWidth; x++){
|
||||||
|
for (y=head.biHeight-1; y>=info.rSelectionBox.top; y--){
|
||||||
|
if (pSelection[x+y*head.biWidth]){
|
||||||
|
info.rSelectionBox.top = y+1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Gets the Selection level for a single pixel
|
||||||
|
* "blind" version assumes that (x,y) is inside to the image.
|
||||||
|
*/
|
||||||
|
uint8_t CxImage::BlindSelectionGet(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (!IsInside(x,y) || (pSelection==0))
|
||||||
|
#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return pSelection[x+y*head.biWidth];
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Returns pointer to selection data for pixel (x,y).
|
||||||
|
*/
|
||||||
|
uint8_t* CxImage::SelectionGetPointer(const int32_t x,const int32_t y)
|
||||||
|
{
|
||||||
|
if (pSelection && IsInside(x,y)) return pSelection+x+y*head.biWidth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::SelectionFlip()
|
||||||
|
{
|
||||||
|
if (!pSelection) return false;
|
||||||
|
|
||||||
|
uint8_t *buff = (uint8_t*)malloc(head.biWidth);
|
||||||
|
if (!buff) return false;
|
||||||
|
|
||||||
|
uint8_t *iSrc,*iDst;
|
||||||
|
iSrc = pSelection + (head.biHeight-1)*head.biWidth;
|
||||||
|
iDst = pSelection;
|
||||||
|
for (int32_t i=0; i<(head.biHeight/2); ++i)
|
||||||
|
{
|
||||||
|
memcpy(buff, iSrc, head.biWidth);
|
||||||
|
memcpy(iSrc, iDst, head.biWidth);
|
||||||
|
memcpy(iDst, buff, head.biWidth);
|
||||||
|
iSrc-=head.biWidth;
|
||||||
|
iDst+=head.biWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buff);
|
||||||
|
|
||||||
|
int32_t top = info.rSelectionBox.top;
|
||||||
|
info.rSelectionBox.top = head.biHeight - info.rSelectionBox.bottom;
|
||||||
|
info.rSelectionBox.bottom = head.biHeight - top;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImage::SelectionMirror()
|
||||||
|
{
|
||||||
|
if (!pSelection) return false;
|
||||||
|
uint8_t* pSelection2 = (uint8_t*)malloc(head.biWidth * head.biHeight);
|
||||||
|
if (!pSelection2) return false;
|
||||||
|
|
||||||
|
uint8_t *iSrc,*iDst;
|
||||||
|
int32_t wdt=head.biWidth-1;
|
||||||
|
iSrc=pSelection + wdt;
|
||||||
|
iDst=pSelection2;
|
||||||
|
for(int32_t y=0; y < head.biHeight; y++){
|
||||||
|
for(int32_t x=0; x <= wdt; x++)
|
||||||
|
*(iDst+x)=*(iSrc-x);
|
||||||
|
iSrc+=head.biWidth;
|
||||||
|
iDst+=head.biWidth;
|
||||||
|
}
|
||||||
|
free(pSelection);
|
||||||
|
pSelection=pSelection2;
|
||||||
|
|
||||||
|
int32_t left = info.rSelectionBox.left;
|
||||||
|
info.rSelectionBox.left = head.biWidth - info.rSelectionBox.right;
|
||||||
|
info.rSelectionBox.right = head.biWidth - left;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
/**
|
||||||
|
* Converts the selection in a HRGN object.
|
||||||
|
*/
|
||||||
|
bool CxImage::SelectionToHRGN(HRGN& region)
|
||||||
|
{
|
||||||
|
if (pSelection && region){
|
||||||
|
for(int32_t y = 0; y < head.biHeight; y++){
|
||||||
|
HRGN hTemp = NULL;
|
||||||
|
int32_t iStart = -1;
|
||||||
|
int32_t x = 0;
|
||||||
|
for(; x < head.biWidth; x++){
|
||||||
|
if (pSelection[x + y * head.biWidth] != 0){
|
||||||
|
if (iStart == -1) iStart = x;
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
if (iStart >= 0){
|
||||||
|
hTemp = CreateRectRgn(iStart, y, x, y + 1);
|
||||||
|
CombineRgn(region, hTemp, region, RGN_OR);
|
||||||
|
DeleteObject(hTemp);
|
||||||
|
iStart = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iStart >= 0){
|
||||||
|
hTemp = CreateRectRgn(iStart, y, x, y + 1);
|
||||||
|
CombineRgn(region, hTemp, region, RGN_OR);
|
||||||
|
DeleteObject(hTemp);
|
||||||
|
iStart = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif //CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_SELECTION
|
||||||
126
Raw2Bmp_MFC/include/ximaska.cpp
Normal file
126
Raw2Bmp_MFC/include/ximaska.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaska.cpp
|
||||||
|
* Purpose: Platform Independent SKA Image Class Loader and Writer
|
||||||
|
* 25/Sep/2007 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximaska.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageSKA::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile==NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// read the header
|
||||||
|
SKAHEADER ska_header;
|
||||||
|
hFile->Read(&ska_header,sizeof(SKAHEADER),1);
|
||||||
|
|
||||||
|
ska_header.Width = m_ntohs(ska_header.Width);
|
||||||
|
ska_header.Height = m_ntohs(ska_header.Height);
|
||||||
|
ska_header.dwUnknown = m_ntohl(ska_header.dwUnknown);
|
||||||
|
|
||||||
|
// check header
|
||||||
|
if (ska_header.dwUnknown != 0x01000000 ||
|
||||||
|
ska_header.Width > 0x7FFF || ska_header.Height > 0x7FFF ||
|
||||||
|
ska_header.BppExp != 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = ska_header.Width ;
|
||||||
|
head.biHeight= ska_header.Height;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_SKA;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t bpp = 1<<ska_header.BppExp;
|
||||||
|
|
||||||
|
Create(ska_header.Width,ska_header.Height,bpp,CXIMAGE_FORMAT_SKA);
|
||||||
|
if (!IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// read the palette
|
||||||
|
int32_t nColors = 1<<bpp;
|
||||||
|
rgb_color* ppal = (rgb_color*)malloc(nColors*sizeof(rgb_color));
|
||||||
|
if (!ppal) return false;
|
||||||
|
hFile->Read(ppal,nColors*sizeof(rgb_color),1);
|
||||||
|
SetPalette(ppal,nColors);
|
||||||
|
free(ppal);
|
||||||
|
|
||||||
|
//read the image
|
||||||
|
hFile->Read(GetBits(),ska_header.Width*ska_header.Height,1);
|
||||||
|
|
||||||
|
//reorder rows
|
||||||
|
if (GetEffWidth() != ska_header.Width){
|
||||||
|
uint8_t *src,*dst;
|
||||||
|
src = GetBits() + ska_header.Width*(ska_header.Height-1);
|
||||||
|
dst = GetBits(ska_header.Height-1);
|
||||||
|
for(int32_t y=0;y<ska_header.Height;y++){
|
||||||
|
memcpy(dst,src,ska_header.Width);
|
||||||
|
src -= ska_header.Width;
|
||||||
|
dst -= GetEffWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Flip();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageSKA::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
if(head.biBitCount > 8) {
|
||||||
|
strcpy(info.szLastError,"SKA Images must be 8 bit or less");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKAHEADER ska_header;
|
||||||
|
|
||||||
|
ska_header.Width = (uint16_t)GetWidth();
|
||||||
|
ska_header.Height = (uint16_t)GetHeight();
|
||||||
|
ska_header.BppExp = 3;
|
||||||
|
ska_header.dwUnknown = 0x01000000;
|
||||||
|
|
||||||
|
ska_header.Width = m_ntohs(ska_header.Width);
|
||||||
|
ska_header.Height = m_ntohs(ska_header.Height);
|
||||||
|
ska_header.dwUnknown = m_ntohl(ska_header.dwUnknown);
|
||||||
|
|
||||||
|
hFile->Write(&ska_header,sizeof(SKAHEADER),1);
|
||||||
|
|
||||||
|
ska_header.Width = m_ntohs(ska_header.Width);
|
||||||
|
ska_header.Height = m_ntohs(ska_header.Height);
|
||||||
|
ska_header.dwUnknown = m_ntohl(ska_header.dwUnknown);
|
||||||
|
|
||||||
|
if (head.biBitCount<8) IncreaseBpp(8);
|
||||||
|
|
||||||
|
rgb_color pal[256];
|
||||||
|
for(int32_t idx=0; idx<256; idx++){
|
||||||
|
GetPaletteColor(idx,&(pal[idx].r),&(pal[idx].g),&(pal[idx].b));
|
||||||
|
}
|
||||||
|
|
||||||
|
hFile->Write(pal,256*sizeof(rgb_color),1);
|
||||||
|
|
||||||
|
uint8_t* src = GetBits(ska_header.Height-1);
|
||||||
|
for(int32_t y=0;y<ska_header.Height;y++){
|
||||||
|
hFile->Write(src,ska_header.Width,1);
|
||||||
|
src -= GetEffWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_SKA
|
||||||
|
|
||||||
44
Raw2Bmp_MFC/include/ximaska.h
Normal file
44
Raw2Bmp_MFC/include/ximaska.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* File: ximaska.h
|
||||||
|
* Purpose: SKA Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageSKA (c) 25/Sep/2007 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaSKA_h)
|
||||||
|
#define __ximaSKA_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_SKA
|
||||||
|
|
||||||
|
class CxImageSKA: public CxImage
|
||||||
|
{
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct tagSkaHeader {
|
||||||
|
uint16_t Width;
|
||||||
|
uint16_t Height;
|
||||||
|
uint8_t BppExp;
|
||||||
|
uint32_t dwUnknown;
|
||||||
|
} SKAHEADER;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImageSKA(): CxImage(CXIMAGE_FORMAT_SKA) {}
|
||||||
|
|
||||||
|
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
|
||||||
|
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
320
Raw2Bmp_MFC/include/ximatga.cpp
Normal file
320
Raw2Bmp_MFC/include/ximatga.cpp
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
* File: ximatga.cpp
|
||||||
|
* Purpose: Platform Independent TGA Image Class Loader and Writer
|
||||||
|
* 05/Jan/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximatga.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
|
||||||
|
#include "ximaiter.h"
|
||||||
|
|
||||||
|
// Definitions for image types.
|
||||||
|
#define TGA_Null 0
|
||||||
|
#define TGA_Map 1
|
||||||
|
#define TGA_RGB 2
|
||||||
|
#define TGA_Mono 3
|
||||||
|
#define TGA_RLEMap 9
|
||||||
|
#define TGA_RLERGB 10
|
||||||
|
#define TGA_RLEMono 11
|
||||||
|
#define TGA_CompMap 32
|
||||||
|
#define TGA_CompMap4 33
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageTGA::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
TGAHEADER tgaHead;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (hFile->Read(&tgaHead,sizeof(tgaHead),1)==0)
|
||||||
|
cx_throw("Not a TGA");
|
||||||
|
|
||||||
|
tga_toh(&tgaHead);
|
||||||
|
|
||||||
|
bool bCompressed;
|
||||||
|
switch (tgaHead.ImageType){
|
||||||
|
case TGA_Map:
|
||||||
|
case TGA_RGB:
|
||||||
|
case TGA_Mono:
|
||||||
|
bCompressed = false;
|
||||||
|
break;
|
||||||
|
case TGA_RLEMap:
|
||||||
|
case TGA_RLERGB:
|
||||||
|
case TGA_RLEMono:
|
||||||
|
bCompressed = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cx_throw("Unknown TGA image type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgaHead.ImageWidth==0 || tgaHead.ImageHeight==0 || tgaHead.PixelDepth==0 || tgaHead.CmapLength>256)
|
||||||
|
cx_throw("bad TGA header");
|
||||||
|
|
||||||
|
if (tgaHead.PixelDepth!=8 && tgaHead.PixelDepth!=15 && tgaHead.PixelDepth!=16 && tgaHead.PixelDepth!=24 && tgaHead.PixelDepth!=32)
|
||||||
|
cx_throw("bad TGA header");
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
head.biWidth = tgaHead.ImageWidth ;
|
||||||
|
head.biHeight= tgaHead.ImageHeight;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_TGA;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgaHead.IdLength>0) hFile->Seek(tgaHead.IdLength,SEEK_CUR); //skip descriptor
|
||||||
|
|
||||||
|
Create(tgaHead.ImageWidth, tgaHead.ImageHeight, tgaHead.PixelDepth, CXIMAGE_FORMAT_TGA);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
if (tgaHead.PixelDepth==32) AlphaCreate(); // Image has alpha channel
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
if (!IsValid()) cx_throw("TGA Create failed");
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
if (tgaHead.CmapType != 0){ // read the palette
|
||||||
|
rgb_color pal[256];
|
||||||
|
hFile->Read(pal,tgaHead.CmapLength*sizeof(rgb_color), 1);
|
||||||
|
for (int32_t i=0;i<tgaHead.CmapLength; i++) SetPaletteColor((uint8_t)i,pal[i].b,pal[i].g,pal[i].r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgaHead.ImageType == TGA_Mono || tgaHead.ImageType == TGA_RLEMono)
|
||||||
|
SetGrayPalette();
|
||||||
|
|
||||||
|
// Bits 4 & 5 of the Image Descriptor byte control the ordering of the pixels.
|
||||||
|
bool bXReversed = ((tgaHead.ImagDesc & 16) == 16);
|
||||||
|
bool bYReversed = ((tgaHead.ImagDesc & 32) == 32);
|
||||||
|
|
||||||
|
CImageIterator iter(this);
|
||||||
|
uint8_t rleLeftover = 255; //for images with illegal packet boundary
|
||||||
|
uint8_t* pDest;
|
||||||
|
for (int32_t y=0; y < tgaHead.ImageHeight; y++){
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
if (hFile == NULL || hFile->Eof()) cx_throw("corrupted TGA");
|
||||||
|
|
||||||
|
if (bYReversed) pDest = iter.GetRow(tgaHead.ImageHeight-y-1);
|
||||||
|
else pDest = iter.GetRow(y);
|
||||||
|
|
||||||
|
if (bCompressed) rleLeftover = ExpandCompressedLine(pDest,&tgaHead,hFile,tgaHead.ImageWidth,y,rleLeftover);
|
||||||
|
else ExpandUncompressedLine (pDest,&tgaHead,hFile,tgaHead.ImageWidth,y,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bXReversed) Mirror();
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (bYReversed && tgaHead.PixelDepth==32) AlphaFlip(); //<lioucr>
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageTGA::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
if (head.biBitCount<8){
|
||||||
|
strcpy(info.szLastError,"Bit depth must be 8 or 24");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAHEADER tgaHead;
|
||||||
|
|
||||||
|
tgaHead.IdLength = 0; // Image ID Field Length
|
||||||
|
tgaHead.CmapType = GetPalette()!=0; // Color Map Type
|
||||||
|
tgaHead.ImageType = (head.biBitCount == 8) ? (uint8_t)TGA_Map : (uint8_t)TGA_RGB; // Image Type
|
||||||
|
|
||||||
|
tgaHead.CmapIndex=0; // First Entry Index
|
||||||
|
tgaHead.CmapLength=(head.biBitCount == 8) ? 256 : 0; // Color Map Length
|
||||||
|
tgaHead.CmapEntrySize=(head.biBitCount == 8) ? (uint8_t)24 : (uint8_t)0; // Color Map Entry Size
|
||||||
|
|
||||||
|
tgaHead.X_Origin=0; // X-origin of Image
|
||||||
|
tgaHead.Y_Origin=0; // Y-origin of Image
|
||||||
|
tgaHead.ImageWidth=(uint16_t)head.biWidth; // Image Width
|
||||||
|
tgaHead.ImageHeight=(uint16_t)head.biHeight; // Image Height
|
||||||
|
tgaHead.PixelDepth=(uint8_t)head.biBitCount; // Pixel Depth
|
||||||
|
tgaHead.ImagDesc=0; // Image Descriptor
|
||||||
|
|
||||||
|
if (pAlpha && head.biBitCount==24) tgaHead.PixelDepth=32;
|
||||||
|
|
||||||
|
tga_toh(&tgaHead);
|
||||||
|
hFile->Write(&tgaHead,sizeof(TGAHEADER),1);
|
||||||
|
tga_toh(&tgaHead);
|
||||||
|
|
||||||
|
if (head.biBitCount==8){
|
||||||
|
rgb_color pal[256];
|
||||||
|
RGBQUAD* ppal = GetPalette();
|
||||||
|
for (int32_t i=0;i<256; i++){
|
||||||
|
pal[i].r = ppal[i].rgbBlue;
|
||||||
|
pal[i].g = ppal[i].rgbGreen;
|
||||||
|
pal[i].b = ppal[i].rgbRed;
|
||||||
|
}
|
||||||
|
hFile->Write(&pal,256*sizeof(rgb_color),1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageIterator iter(this);
|
||||||
|
uint8_t* pDest;
|
||||||
|
if (pAlpha==0 || head.biBitCount==8){
|
||||||
|
for (int32_t y=0; y < tgaHead.ImageHeight; y++){
|
||||||
|
pDest = iter.GetRow(y);
|
||||||
|
hFile->Write(pDest,tgaHead.ImageWidth * (head.biBitCount >> 3),1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pDest = (uint8_t*)malloc(4*tgaHead.ImageWidth);
|
||||||
|
RGBQUAD c;
|
||||||
|
for (int32_t y=0; y < tgaHead.ImageHeight; y++){
|
||||||
|
for(int32_t x=0, x4=0;x<tgaHead.ImageWidth;x++, x4+=4){
|
||||||
|
c = BlindGetPixelColor(x,y);
|
||||||
|
pDest[x4+0]=c.rgbBlue;
|
||||||
|
pDest[x4+1]=c.rgbGreen;
|
||||||
|
pDest[x4+2]=c.rgbRed;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
pDest[x4+3]=AlphaGet(x,y);
|
||||||
|
#else
|
||||||
|
pDest[x4+3]=0;
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
hFile->Write(pDest,4*tgaHead.ImageWidth,1);
|
||||||
|
}
|
||||||
|
free(pDest);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
uint8_t CxImageTGA::ExpandCompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, uint8_t rleLeftover)
|
||||||
|
{
|
||||||
|
uint8_t rle;
|
||||||
|
int32_t filePos=0;
|
||||||
|
for (int32_t x=0; x<width; ){
|
||||||
|
if (rleLeftover != 255){
|
||||||
|
rle = rleLeftover;
|
||||||
|
rleLeftover = 255;
|
||||||
|
} else {
|
||||||
|
hFile->Read(&rle,1,1);
|
||||||
|
}
|
||||||
|
if (rle & 128) { // RLE-Encoded packet
|
||||||
|
rle -= 127; // Calculate real repeat count.
|
||||||
|
if ((x+rle)>width){
|
||||||
|
rleLeftover = (uint8_t)(128 + (rle - (width - x) - 1));
|
||||||
|
filePos = hFile->Tell();
|
||||||
|
rle = (uint8_t)(width - x);
|
||||||
|
}
|
||||||
|
switch (ptgaHead->PixelDepth)
|
||||||
|
{
|
||||||
|
case 32: {
|
||||||
|
RGBQUAD color;
|
||||||
|
hFile->Read(&color,4,1);
|
||||||
|
for (int32_t ix = 0; ix < rle; ix++){
|
||||||
|
memcpy(&pDest[3*ix],&color,3);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
AlphaSet(ix+x,y,color.rgbReserved);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24: {
|
||||||
|
rgb_color triple;
|
||||||
|
hFile->Read(&triple,3,1);
|
||||||
|
for (int32_t ix = 0; ix < rle; ix++) memcpy(&pDest[3*ix],&triple,3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 15:
|
||||||
|
case 16: {
|
||||||
|
uint16_t pixel;
|
||||||
|
hFile->Read(&pixel,2,1);
|
||||||
|
rgb_color triple;
|
||||||
|
triple.r = (uint8_t)(( pixel & 0x1F ) * 8); // red
|
||||||
|
triple.g = (uint8_t)(( pixel >> 2 ) & 0x0F8); // green
|
||||||
|
triple.b = (uint8_t)(( pixel >> 7 ) & 0x0F8); // blue
|
||||||
|
for (int32_t ix = 0; ix < rle; ix++){
|
||||||
|
memcpy(&pDest[3*ix],&triple,3);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8: {
|
||||||
|
uint8_t pixel;
|
||||||
|
hFile->Read(&pixel,1,1);
|
||||||
|
for (int32_t ix = 0; ix < rle; ix++) pDest[ix] = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rleLeftover!=255) hFile->Seek(filePos, SEEK_SET);
|
||||||
|
} else { // Raw packet
|
||||||
|
rle += 1; // Calculate real repeat count.
|
||||||
|
if ((x+rle)>width){
|
||||||
|
rleLeftover = (uint8_t)(rle - (width - x) - 1);
|
||||||
|
rle = (uint8_t)(width - x);
|
||||||
|
}
|
||||||
|
ExpandUncompressedLine(pDest,ptgaHead,hFile,rle,y,x);
|
||||||
|
}
|
||||||
|
if (head.biBitCount == 24) pDest += rle*3; else pDest += rle;
|
||||||
|
x += rle;
|
||||||
|
}
|
||||||
|
return rleLeftover;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageTGA::ExpandUncompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, int32_t xoffset)
|
||||||
|
{
|
||||||
|
switch (ptgaHead->PixelDepth){
|
||||||
|
case 8:
|
||||||
|
hFile->Read(pDest,width,1);
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
case 16:{
|
||||||
|
uint8_t* dst=pDest;
|
||||||
|
uint16_t pixel;
|
||||||
|
for (int32_t x=0; x<width; x++){
|
||||||
|
hFile->Read(&pixel,2,1);
|
||||||
|
*dst++ = (uint8_t)(( pixel & 0x1F ) * 8); // blue
|
||||||
|
*dst++ = (uint8_t)(( pixel >> 2 ) & 0x0F8); // green
|
||||||
|
*dst++ = (uint8_t)(( pixel >> 7 ) & 0x0F8); // red
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24:
|
||||||
|
hFile->Read(pDest,3*width,1);
|
||||||
|
break;
|
||||||
|
case 32:{
|
||||||
|
uint8_t* dst=pDest;
|
||||||
|
for (int32_t x=0; x<width; x++){
|
||||||
|
RGBQUAD pixel;
|
||||||
|
hFile->Read(&pixel,4,1);
|
||||||
|
*dst++ = pixel.rgbBlue;
|
||||||
|
*dst++ = pixel.rgbGreen;
|
||||||
|
*dst++ = pixel.rgbRed;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA // <vho>
|
||||||
|
AlphaSet(x+xoffset,y,pixel.rgbReserved); //alpha
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageTGA::tga_toh(TGAHEADER* p)
|
||||||
|
{
|
||||||
|
p->CmapIndex = m_ntohs(p->CmapIndex);
|
||||||
|
p->CmapLength = m_ntohs(p->CmapLength);
|
||||||
|
p->X_Origin = m_ntohs(p->X_Origin);
|
||||||
|
p->Y_Origin = m_ntohs(p->Y_Origin);
|
||||||
|
p->ImageWidth = m_ntohs(p->ImageWidth);
|
||||||
|
p->ImageHeight = m_ntohs(p->ImageHeight);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_TGA
|
||||||
61
Raw2Bmp_MFC/include/ximatga.h
Normal file
61
Raw2Bmp_MFC/include/ximatga.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* File: ximatga.h
|
||||||
|
* Purpose: TARGA Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageTGA (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Parts of the code come from Paintlib : Copyright (c) 1996-1998 Ulrich von Zadow
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaTGA_h)
|
||||||
|
#define __ximaTGA_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TGA
|
||||||
|
|
||||||
|
class CxImageTGA: public CxImage
|
||||||
|
{
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct tagTgaHeader
|
||||||
|
{
|
||||||
|
uint8_t IdLength; // Image ID Field Length
|
||||||
|
uint8_t CmapType; // Color Map Type
|
||||||
|
uint8_t ImageType; // Image Type
|
||||||
|
|
||||||
|
uint16_t CmapIndex; // First Entry Index
|
||||||
|
uint16_t CmapLength; // Color Map Length
|
||||||
|
uint8_t CmapEntrySize; // Color Map Entry Size
|
||||||
|
|
||||||
|
uint16_t X_Origin; // X-origin of Image
|
||||||
|
uint16_t Y_Origin; // Y-origin of Image
|
||||||
|
uint16_t ImageWidth; // Image Width
|
||||||
|
uint16_t ImageHeight; // Image Height
|
||||||
|
uint8_t PixelDepth; // Pixel Depth
|
||||||
|
uint8_t ImagDesc; // Image Descriptor
|
||||||
|
} TGAHEADER;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImageTGA(): CxImage(CXIMAGE_FORMAT_TGA) {}
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TGA);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TGA);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
protected:
|
||||||
|
uint8_t ExpandCompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, uint8_t rleLeftover);
|
||||||
|
void ExpandUncompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, int32_t xoffset);
|
||||||
|
void tga_toh(TGAHEADER* p);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
97
Raw2Bmp_MFC/include/ximath.cpp
Normal file
97
Raw2Bmp_MFC/include/ximath.cpp
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#include "ximage.h"
|
||||||
|
#include "ximath.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
//this module should contain some classes for geometrical transformations
|
||||||
|
//usable with selections, etc... once it's done, that is. :)
|
||||||
|
|
||||||
|
CxPoint2::CxPoint2()
|
||||||
|
{
|
||||||
|
x=y=0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CxPoint2::CxPoint2(float const x_, float const y_)
|
||||||
|
{
|
||||||
|
x=x_;
|
||||||
|
y=y_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CxPoint2::CxPoint2(CxPoint2 const &p)
|
||||||
|
{
|
||||||
|
x=p.x;
|
||||||
|
y=p.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CxPoint2::Distance(CxPoint2 const p2)
|
||||||
|
{
|
||||||
|
return (float)sqrt((x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
float CxPoint2::Distance(float const x_, float const y_)
|
||||||
|
{
|
||||||
|
return (float)sqrt((x-x_)*(x-x_)+(y-y_)*(y-y_));
|
||||||
|
}
|
||||||
|
|
||||||
|
CxRect2::CxRect2()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CxRect2::CxRect2(float const x1_, float const y1_, float const x2_, float const y2_)
|
||||||
|
{
|
||||||
|
botLeft.x=x1_;
|
||||||
|
botLeft.y=y1_;
|
||||||
|
topRight.x=x2_;
|
||||||
|
topRight.y=y2_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CxRect2::CxRect2(CxRect2 const &p)
|
||||||
|
{
|
||||||
|
botLeft=p.botLeft;
|
||||||
|
topRight=p.topRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CxRect2::Surface() const
|
||||||
|
/*
|
||||||
|
* Returns the surface of rectangle.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return (topRight.x-botLeft.x)*(topRight.y-botLeft.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
CxRect2 CxRect2::CrossSection(CxRect2 const &r2) const
|
||||||
|
/*
|
||||||
|
* Returns crossection with another rectangle.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
CxRect2 cs;
|
||||||
|
cs.botLeft.x=max(botLeft.x, r2.botLeft.x);
|
||||||
|
cs.botLeft.y=max(botLeft.y, r2.botLeft.y);
|
||||||
|
cs.topRight.x=min(topRight.x, r2.topRight.x);
|
||||||
|
cs.topRight.y=min(topRight.y, r2.topRight.y);
|
||||||
|
if (cs.botLeft.x<=cs.topRight.x && cs.botLeft.y<=cs.topRight.y) {
|
||||||
|
return cs;
|
||||||
|
} else {
|
||||||
|
return CxRect2(0,0,0,0);
|
||||||
|
}//if
|
||||||
|
}
|
||||||
|
|
||||||
|
CxPoint2 CxRect2::Center() const
|
||||||
|
/*
|
||||||
|
* Returns the center point of rectangle.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return CxPoint2((topRight.x+botLeft.x)/2.0f, (topRight.y+botLeft.y)/2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CxRect2::Width() const
|
||||||
|
//returns rectangle width
|
||||||
|
{
|
||||||
|
return topRight.x-botLeft.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CxRect2::Height() const
|
||||||
|
//returns rectangle height
|
||||||
|
{
|
||||||
|
return topRight.y-botLeft.y;
|
||||||
|
}
|
||||||
|
|
||||||
39
Raw2Bmp_MFC/include/ximath.h
Normal file
39
Raw2Bmp_MFC/include/ximath.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#if !defined(__ximath_h)
|
||||||
|
#define __ximath_h
|
||||||
|
|
||||||
|
#include "ximadef.h"
|
||||||
|
|
||||||
|
//***bd*** simple floating point point
|
||||||
|
class DLL_EXP CxPoint2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxPoint2();
|
||||||
|
CxPoint2(float const x_, float const y_);
|
||||||
|
CxPoint2(CxPoint2 const &p);
|
||||||
|
|
||||||
|
float Distance(CxPoint2 const p2);
|
||||||
|
float Distance(float const x_, float const y_);
|
||||||
|
|
||||||
|
float x,y;
|
||||||
|
};
|
||||||
|
|
||||||
|
//and simple rectangle
|
||||||
|
class DLL_EXP CxRect2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxRect2();
|
||||||
|
CxRect2(float const x1_, float const y1_, float const x2_, float const y2_);
|
||||||
|
CxRect2(CxPoint2 const &bl, CxPoint2 const &tr);
|
||||||
|
CxRect2(CxRect2 const &p);
|
||||||
|
|
||||||
|
float Surface() const;
|
||||||
|
CxRect2 CrossSection(CxRect2 const &r2) const;
|
||||||
|
CxPoint2 Center() const;
|
||||||
|
float Width() const;
|
||||||
|
float Height() const;
|
||||||
|
|
||||||
|
CxPoint2 botLeft;
|
||||||
|
CxPoint2 topRight;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
982
Raw2Bmp_MFC/include/ximatif.cpp
Normal file
982
Raw2Bmp_MFC/include/ximatif.cpp
Normal file
@@ -0,0 +1,982 @@
|
|||||||
|
/*
|
||||||
|
* File: ximatif.cpp
|
||||||
|
* Purpose: Platform Independent TIFF Image Class Loader and Writer
|
||||||
|
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximatif.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
|
||||||
|
#define FIX_16BPP_DARKIMG // + VK: if uncomment, dark 16bpp images are fixed
|
||||||
|
|
||||||
|
#include "../tiff/tiffio.h"
|
||||||
|
|
||||||
|
#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
|
||||||
|
#define SCALE(x) (((x)*((1L<<16)-1))/255)
|
||||||
|
#define CalculateLine(width,bitdepth) (((width * bitdepth) + 7) / 8)
|
||||||
|
#define CalculatePitch(line) (line + 3 & ~3)
|
||||||
|
|
||||||
|
extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
CxImageTIF::~CxImageTIF()
|
||||||
|
{
|
||||||
|
if (m_tif2) TIFFClose(m_tif2);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageTIF::Decode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
//Comment this line if you need more information on errors
|
||||||
|
// TIFFSetErrorHandler(NULL); //<Patrick Hoffmann>
|
||||||
|
|
||||||
|
//Open file and fill the TIFF structure
|
||||||
|
// m_tif = TIFFOpen(imageFileName,"rb");
|
||||||
|
TIFF* m_tif = _TIFFOpenEx(hFile, "rb");
|
||||||
|
|
||||||
|
uint32 height=0;
|
||||||
|
uint32 width=0;
|
||||||
|
uint16 bitspersample=1;
|
||||||
|
uint16 samplesperpixel=1;
|
||||||
|
uint32 rowsperstrip=(uint32_t)-1;
|
||||||
|
uint16 photometric=0;
|
||||||
|
uint16 compression=1;
|
||||||
|
uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
|
||||||
|
uint16 res_unit; //<Trifon>
|
||||||
|
uint32 x, y;
|
||||||
|
float resolution, offset;
|
||||||
|
BOOL isRGB;
|
||||||
|
uint8_t *bits; //pointer to source data
|
||||||
|
uint8_t *bits2; //pointer to destination data
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
//check if it's a tiff file
|
||||||
|
if (!m_tif)
|
||||||
|
cx_throw("Error encountered while opening TIFF file");
|
||||||
|
|
||||||
|
// <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping
|
||||||
|
// info.nNumFrames=0;
|
||||||
|
// while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++;
|
||||||
|
info.nNumFrames = TIFFNumberOfDirectories(m_tif);
|
||||||
|
|
||||||
|
if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame))
|
||||||
|
cx_throw("Error: page not present in TIFF file");
|
||||||
|
|
||||||
|
//get image info
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation);
|
||||||
|
|
||||||
|
if (info.nEscape == -1) {
|
||||||
|
// Return output dimensions only
|
||||||
|
head.biWidth = width;
|
||||||
|
head.biHeight = height;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_TIF;
|
||||||
|
cx_throw("output dimensions returned");
|
||||||
|
}
|
||||||
|
|
||||||
|
TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
|
||||||
|
if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution))
|
||||||
|
{
|
||||||
|
if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
|
||||||
|
SetXDPI((int32_t)resolution);
|
||||||
|
}
|
||||||
|
if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
|
||||||
|
{
|
||||||
|
if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
|
||||||
|
SetYDPI((int32_t)resolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset)) info.xOffset = (int32_t)offset;
|
||||||
|
if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset)) info.yOffset = (int32_t)offset;
|
||||||
|
|
||||||
|
head.biClrUsed=0;
|
||||||
|
info.nBkgndIndex =-1;
|
||||||
|
|
||||||
|
if (rowsperstrip>height){
|
||||||
|
rowsperstrip=height;
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
isRGB = /*(bitspersample >= 8) && (VK: it is possible so for RGB to have < 8 bpp!)*/
|
||||||
|
(photometric == PHOTOMETRIC_RGB) ||
|
||||||
|
(photometric == PHOTOMETRIC_YCBCR) ||
|
||||||
|
(photometric == PHOTOMETRIC_SEPARATED) ||
|
||||||
|
(photometric == PHOTOMETRIC_LOGL) ||
|
||||||
|
(photometric == PHOTOMETRIC_LOGLUV);
|
||||||
|
|
||||||
|
if (isRGB){
|
||||||
|
head.biBitCount=24;
|
||||||
|
}else{
|
||||||
|
if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)||(photometric==PHOTOMETRIC_PALETTE)){
|
||||||
|
if (bitspersample == 1){
|
||||||
|
head.biBitCount=1; //B&W image
|
||||||
|
head.biClrUsed =2;
|
||||||
|
} else if (bitspersample == 4) {
|
||||||
|
head.biBitCount=4; //16 colors gray scale
|
||||||
|
head.biClrUsed =16;
|
||||||
|
} else {
|
||||||
|
head.biBitCount=8; //gray scale
|
||||||
|
head.biClrUsed =256;
|
||||||
|
}
|
||||||
|
} else if (bitspersample == 4) {
|
||||||
|
head.biBitCount=4; // 16 colors
|
||||||
|
head.biClrUsed=16;
|
||||||
|
} else {
|
||||||
|
head.biBitCount=8; //256 colors
|
||||||
|
head.biClrUsed=256;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bitspersample > 8) && (photometric==PHOTOMETRIC_PALETTE)) // + VK + (BIG palette! => convert to RGB)
|
||||||
|
{ head.biBitCount=24;
|
||||||
|
head.biClrUsed =0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
|
||||||
|
|
||||||
|
Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF); //image creation
|
||||||
|
if (!pDib) cx_throw("CxImageTIF can't create image");
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (samplesperpixel==4) AlphaCreate(); //add alpha support for 32bpp tiffs
|
||||||
|
if (samplesperpixel==2 && bitspersample==8) AlphaCreate(); //add alpha support for 8bpp + alpha
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
|
||||||
|
SetCodecOption(compression); // <DPR> save original compression type
|
||||||
|
|
||||||
|
if (isRGB) {
|
||||||
|
// Read the whole image into one big RGBA buffer using
|
||||||
|
// the traditional TIFFReadRGBAImage() API that we trust.
|
||||||
|
uint32* raster; // retrieve RGBA image
|
||||||
|
uint32 *row;
|
||||||
|
|
||||||
|
raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32));
|
||||||
|
if (raster == NULL) cx_throw("No space for raster buffer");
|
||||||
|
|
||||||
|
// Read the image in one chunk into an RGBA array
|
||||||
|
if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) {
|
||||||
|
_TIFFfree(raster);
|
||||||
|
cx_throw("Corrupted TIFF file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the raster lines and save them in the DIB
|
||||||
|
// with RGB mode, we have to change the order of the 3 samples RGB
|
||||||
|
row = &raster[0];
|
||||||
|
bits2 = info.pImage;
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
|
||||||
|
if (info.nEscape){ // <vho> - cancel decoding
|
||||||
|
_TIFFfree(raster);
|
||||||
|
cx_throw("Cancelled");
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = bits2;
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
*bits++ = (uint8_t)TIFFGetB(row[x]);
|
||||||
|
*bits++ = (uint8_t)TIFFGetG(row[x]);
|
||||||
|
*bits++ = (uint8_t)TIFFGetR(row[x]);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (samplesperpixel==4) AlphaSet(x,y,(uint8_t)TIFFGetA(row[x]));
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
row += width;
|
||||||
|
bits2 += info.dwEffWidth;
|
||||||
|
}
|
||||||
|
_TIFFfree(raster);
|
||||||
|
} else {
|
||||||
|
int32_t BIG_palette = (bitspersample > 8) && // + VK
|
||||||
|
(photometric==PHOTOMETRIC_PALETTE);
|
||||||
|
if (BIG_palette && (bitspersample > 24)) // + VK
|
||||||
|
cx_throw("Too big palette to handle"); // + VK
|
||||||
|
|
||||||
|
RGBQUAD *pal;
|
||||||
|
pal=(RGBQUAD*)calloc(BIG_palette ? 1<<bitspersample : 256,sizeof(RGBQUAD));
|
||||||
|
// ! VK: it coasts nothing but more correct to use 256 as temp palette storage
|
||||||
|
// ! VK: but for case of BIG palette it just copied
|
||||||
|
if (pal==NULL) cx_throw("Unable to allocate TIFF palette");
|
||||||
|
|
||||||
|
int32_t bpp = bitspersample <= 8 ? bitspersample : 8; // + VK (to use instead of bitspersample for case of > 8)
|
||||||
|
|
||||||
|
// set up the colormap based on photometric
|
||||||
|
switch(photometric) {
|
||||||
|
case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types
|
||||||
|
case PHOTOMETRIC_MINISWHITE:
|
||||||
|
if (bitspersample == 1) { // Monochrome image
|
||||||
|
if (photometric == PHOTOMETRIC_MINISBLACK) {
|
||||||
|
pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
|
||||||
|
} else {
|
||||||
|
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
|
||||||
|
}
|
||||||
|
} else { // need to build the scale for greyscale images
|
||||||
|
if (photometric == PHOTOMETRIC_MINISBLACK) {
|
||||||
|
for (int32_t i=0; i<(1<<bpp); i++){
|
||||||
|
pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(i*(255/((1<<bpp)-1)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int32_t i=0; i<(1<<bpp); i++){
|
||||||
|
pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(255-i*(255/((1<<bpp)-1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PHOTOMETRIC_PALETTE: // color map indexed
|
||||||
|
uint16 *red;
|
||||||
|
uint16 *green;
|
||||||
|
uint16 *blue;
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue);
|
||||||
|
|
||||||
|
// Is the palette 16 or 8 bits ?
|
||||||
|
BOOL Palette16Bits = /*FALSE*/ BIG_palette;
|
||||||
|
if (!BIG_palette) {
|
||||||
|
int32_t n= 1<<bpp;
|
||||||
|
while (n-- > 0) {
|
||||||
|
if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) {
|
||||||
|
Palette16Bits=TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the palette in the DIB
|
||||||
|
for (int32_t i = (1 << ( BIG_palette ? bitspersample : bpp )) - 1; i >= 0; i--) {
|
||||||
|
if (Palette16Bits) {
|
||||||
|
pal[i].rgbRed =(uint8_t) CVT(red[i]);
|
||||||
|
pal[i].rgbGreen = (uint8_t) CVT(green[i]);
|
||||||
|
pal[i].rgbBlue = (uint8_t) CVT(blue[i]);
|
||||||
|
} else {
|
||||||
|
pal[i].rgbRed = (uint8_t) red[i];
|
||||||
|
pal[i].rgbGreen = (uint8_t) green[i];
|
||||||
|
pal[i].rgbBlue = (uint8_t) blue[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!BIG_palette) { // + VK (BIG palette is stored until image is ready)
|
||||||
|
SetPalette(pal,/*head.biClrUsed*/ 1<<bpp); //palette assign // * VK
|
||||||
|
free(pal);
|
||||||
|
pal = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the tiff lines and save them in the DIB
|
||||||
|
uint32 nrow;
|
||||||
|
uint32 ys;
|
||||||
|
int32_t line = CalculateLine(width, bitspersample * samplesperpixel);
|
||||||
|
|
||||||
|
int32_t bitsize = TIFFStripSize(m_tif);
|
||||||
|
//verify bitsize: could be wrong if StripByteCounts is missing.
|
||||||
|
if (bitsize>(int32_t)(head.biSizeImage*samplesperpixel))
|
||||||
|
bitsize = head.biSizeImage*samplesperpixel;
|
||||||
|
if (bitsize<(int32_t)(info.dwEffWidth*rowsperstrip))
|
||||||
|
bitsize = info.dwEffWidth*rowsperstrip;
|
||||||
|
|
||||||
|
if ((bitspersample > 8) && (bitspersample != 16)) // + VK (for bitspersample == 9..15,17..32..64
|
||||||
|
bitsize *= (bitspersample + 7)/8;
|
||||||
|
|
||||||
|
int32_t tiled_image = TIFFIsTiled(m_tif);
|
||||||
|
uint32 tw=0, tl=0;
|
||||||
|
uint8_t* tilebuf=NULL;
|
||||||
|
if (tiled_image){
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
|
||||||
|
TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
|
||||||
|
rowsperstrip = tl;
|
||||||
|
bitsize = TIFFTileSize(m_tif) * (int32_t)(1+width/tw);
|
||||||
|
tilebuf = (uint8_t*)malloc(TIFFTileSize(m_tif));
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
|
||||||
|
uint8_t * bits16 = NULL; // + VK
|
||||||
|
int32_t line16 = 0; // + VK
|
||||||
|
|
||||||
|
if (!tiled_image && bitspersample==16) { // + VK +
|
||||||
|
line16 = line;
|
||||||
|
line = CalculateLine(width, 8 * samplesperpixel);
|
||||||
|
bits16 = bits;
|
||||||
|
bits = (uint8_t*)malloc(bitsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits==NULL){
|
||||||
|
if (bits16) free(bits16); // + VK
|
||||||
|
if (pal) free(pal); // + VK
|
||||||
|
if (tilebuf)free(tilebuf); // + VK
|
||||||
|
cx_throw("CxImageTIF can't allocate memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FIX_16BPP_DARKIMG // + VK: for each line, store shift count bits used to fix it
|
||||||
|
uint8_t* row_shifts = NULL;
|
||||||
|
if (bits16) row_shifts = (uint8_t*)malloc(height);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (ys = 0; ys < height; ys += rowsperstrip) {
|
||||||
|
|
||||||
|
if (info.nEscape){ // <vho> - cancel decoding
|
||||||
|
free(bits);
|
||||||
|
cx_throw("Cancelled");
|
||||||
|
}
|
||||||
|
|
||||||
|
nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);
|
||||||
|
|
||||||
|
if (tiled_image){
|
||||||
|
uint32 imagew = TIFFScanlineSize(m_tif);
|
||||||
|
uint32 tilew = TIFFTileRowSize(m_tif);
|
||||||
|
int32_t iskew = imagew - tilew;
|
||||||
|
uint8* bufp = (uint8*) bits;
|
||||||
|
|
||||||
|
uint32 colb = 0;
|
||||||
|
for (uint32 col = 0; col < width; col += tw) {
|
||||||
|
if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){
|
||||||
|
free(tilebuf);
|
||||||
|
free(bits);
|
||||||
|
cx_throw("Corrupted tiled TIFF file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colb + tw > imagew) {
|
||||||
|
uint32 owidth = imagew - colb;
|
||||||
|
uint32 oskew = tilew - owidth;
|
||||||
|
TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew );
|
||||||
|
} else {
|
||||||
|
TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0);
|
||||||
|
}
|
||||||
|
colb += tilew;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0),
|
||||||
|
(bits16? bits16 : bits), nrow * (bits16 ? line16 : line)) == -1) { // * VK
|
||||||
|
|
||||||
|
#ifdef NOT_IGNORE_CORRUPTED
|
||||||
|
free(bits);
|
||||||
|
if (bits16) free(bits16); // + VK
|
||||||
|
cx_throw("Corrupted TIFF file!");
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y = 0; y < nrow; y++) {
|
||||||
|
int32_t offset=(nrow-y-1)*line;
|
||||||
|
if ((bitspersample==16) && !BIG_palette) { // * VK
|
||||||
|
int32_t offset16 = (nrow-y-1)*line16; // + VK
|
||||||
|
if (bits16) { // + VK +
|
||||||
|
#ifdef FIX_16BPP_DARKIMG
|
||||||
|
int32_t the_shift;
|
||||||
|
uint8_t hi_byte, hi_max=0;
|
||||||
|
uint32_t xi;
|
||||||
|
for (xi=0;xi<(uint32)line;xi++) {
|
||||||
|
hi_byte = bits16[xi*2+offset16+1];
|
||||||
|
if(hi_byte>hi_max)
|
||||||
|
hi_max = hi_byte;
|
||||||
|
}
|
||||||
|
the_shift = (hi_max == 0) ? 8 : 0;
|
||||||
|
if (!the_shift)
|
||||||
|
while( ! (hi_max & 0x80) ) {
|
||||||
|
the_shift++;
|
||||||
|
hi_max <<= 1;
|
||||||
|
}
|
||||||
|
row_shifts[height-ys-nrow+y] = the_shift;
|
||||||
|
the_shift = 8 - the_shift;
|
||||||
|
for (xi=0;xi<(uint32)line;xi++)
|
||||||
|
bits[xi+offset]= ((bits16[xi*2+offset16+1]<<8) | bits16[xi*2+offset16]) >> the_shift;
|
||||||
|
#else
|
||||||
|
for (uint32_t xi=0;xi<(uint32)line;xi++)
|
||||||
|
bits[xi+offset]=bits16[xi*2+offset16+1];
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
for (uint32_t xi=0;xi<width;xi++)
|
||||||
|
bits[xi+offset]=bits[xi*2+offset+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (samplesperpixel==1) {
|
||||||
|
if (BIG_palette)
|
||||||
|
if (bits16) {
|
||||||
|
int32_t offset16 = (nrow-y-1)*line16; // + VK
|
||||||
|
MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
|
||||||
|
bits16 + offset16, width, bitspersample, pal );
|
||||||
|
} else
|
||||||
|
MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
|
||||||
|
bits + offset, width, bitspersample, pal );
|
||||||
|
else if ((bitspersample == head.biBitCount) ||
|
||||||
|
(bitspersample == 16)) //simple 8bpp, 4bpp image or 16bpp
|
||||||
|
memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,min((unsigned)line, info.dwEffWidth));
|
||||||
|
else
|
||||||
|
MoveBits( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
|
||||||
|
bits + offset, width, bitspersample );
|
||||||
|
} else if (samplesperpixel==2) { //8bpp image with alpha layer
|
||||||
|
int32_t xi=0;
|
||||||
|
int32_t ii=0;
|
||||||
|
int32_t yi=height-ys-nrow+y;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (!pAlpha) AlphaCreate(); // + VK
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
while (ii<line){
|
||||||
|
SetPixelIndex(xi,yi,bits[ii+offset]);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
AlphaSet(xi,yi,bits[ii+offset+1]);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
ii+=2;
|
||||||
|
xi++;
|
||||||
|
if (xi>=(int32_t)width){
|
||||||
|
yi--;
|
||||||
|
xi=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { //photometric==PHOTOMETRIC_CIELAB
|
||||||
|
if (head.biBitCount!=24){ //fix image
|
||||||
|
Create(width,height,24,CXIMAGE_FORMAT_TIF);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (samplesperpixel==4) AlphaCreate();
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t xi=0;
|
||||||
|
uint32 ii=0;
|
||||||
|
int32_t yi=height-ys-nrow+y;
|
||||||
|
RGBQUAD c;
|
||||||
|
int32_t l,a,b,bitsoffset;
|
||||||
|
double p,cx,cy,cz,cr,cg,cb;
|
||||||
|
while (ii</*line*/width){ // * VK
|
||||||
|
bitsoffset = ii*samplesperpixel+offset;
|
||||||
|
l=bits[bitsoffset];
|
||||||
|
a=bits[bitsoffset+1];
|
||||||
|
b=bits[bitsoffset+2];
|
||||||
|
if (a>127) a-=256;
|
||||||
|
if (b>127) b-=256;
|
||||||
|
// lab to xyz
|
||||||
|
p = (l/2.55 + 16) / 116.0;
|
||||||
|
cx = pow( p + a * 0.002, 3);
|
||||||
|
cy = pow( p, 3);
|
||||||
|
cz = pow( p - b * 0.005, 3);
|
||||||
|
// white point
|
||||||
|
cx*=0.95047;
|
||||||
|
//cy*=1.000;
|
||||||
|
cz*=1.0883;
|
||||||
|
// xyz to rgb
|
||||||
|
cr = 3.240479 * cx - 1.537150 * cy - 0.498535 * cz;
|
||||||
|
cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz;
|
||||||
|
cb = 0.055648 * cx - 0.204043 * cy + 1.057311 * cz;
|
||||||
|
|
||||||
|
if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055;
|
||||||
|
else cr = 12.92 * cr;
|
||||||
|
if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055;
|
||||||
|
else cg = 12.92 * cg;
|
||||||
|
if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055;
|
||||||
|
else cb = 12.92 * cb;
|
||||||
|
|
||||||
|
c.rgbRed =(uint8_t)max(0,min(255,(int32_t)(cr*255)));
|
||||||
|
c.rgbGreen=(uint8_t)max(0,min(255,(int32_t)(cg*255)));
|
||||||
|
c.rgbBlue =(uint8_t)max(0,min(255,(int32_t)(cb*255)));
|
||||||
|
|
||||||
|
SetPixelColor(xi,yi,c);
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
ii++;
|
||||||
|
xi++;
|
||||||
|
if (xi>=(int32_t)width){
|
||||||
|
yi--;
|
||||||
|
xi=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(bits);
|
||||||
|
if (bits16) free(bits16);
|
||||||
|
|
||||||
|
#ifdef FIX_16BPP_DARKIMG
|
||||||
|
if (row_shifts && (samplesperpixel == 1) && (bitspersample==16) && !BIG_palette) {
|
||||||
|
// 1. calculate maximum necessary shift
|
||||||
|
int32_t min_row_shift = 8;
|
||||||
|
for( y=0; y<height; y++ ) {
|
||||||
|
if (min_row_shift > row_shifts[y]) min_row_shift = row_shifts[y];
|
||||||
|
}
|
||||||
|
// 2. for rows having less shift value, correct such rows:
|
||||||
|
for( y=0; y<height; y++ ) {
|
||||||
|
if (min_row_shift < row_shifts[y]) {
|
||||||
|
int32_t need_shift = row_shifts[y] - min_row_shift;
|
||||||
|
uint8_t* data = info.pImage + info.dwEffWidth * y;
|
||||||
|
for( x=0; x<width; x++, data++ )
|
||||||
|
*data >>= need_shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row_shifts) free( row_shifts );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (tiled_image) free(tilebuf);
|
||||||
|
if (pal) free(pal);
|
||||||
|
|
||||||
|
switch(orientation){
|
||||||
|
case ORIENTATION_TOPRIGHT: /* row 0 top, col 0 rhs */
|
||||||
|
Mirror();
|
||||||
|
break;
|
||||||
|
case ORIENTATION_BOTRIGHT: /* row 0 bottom, col 0 rhs */
|
||||||
|
Flip();
|
||||||
|
Mirror();
|
||||||
|
break;
|
||||||
|
case ORIENTATION_BOTLEFT: /* row 0 bottom, col 0 lhs */
|
||||||
|
Flip();
|
||||||
|
break;
|
||||||
|
case ORIENTATION_LEFTTOP: /* row 0 lhs, col 0 top */
|
||||||
|
RotateRight();
|
||||||
|
Mirror();
|
||||||
|
break;
|
||||||
|
case ORIENTATION_RIGHTTOP: /* row 0 rhs, col 0 top */
|
||||||
|
RotateLeft();
|
||||||
|
break;
|
||||||
|
case ORIENTATION_RIGHTBOT: /* row 0 rhs, col 0 bottom */
|
||||||
|
RotateLeft();
|
||||||
|
Mirror();
|
||||||
|
break;
|
||||||
|
case ORIENTATION_LEFTBOT: /* row 0 lhs, col 0 bottom */
|
||||||
|
RotateRight();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (m_tif) TIFFClose(m_tif);
|
||||||
|
if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_TIF) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TIFFClose(m_tif);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageTIF::Encode(CxFile * hFile, bool bAppend)
|
||||||
|
{
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (hFile==NULL) cx_throw(CXIMAGE_ERR_NOFILE);
|
||||||
|
if (pDib==NULL) cx_throw(CXIMAGE_ERR_NOIMAGE);
|
||||||
|
|
||||||
|
// <RJ> replaced "w+b" with "a", to append an image directly on an existing file
|
||||||
|
if (m_tif2==NULL) m_tif2=_TIFFOpenEx(hFile, "a");
|
||||||
|
if (m_tif2==NULL) cx_throw("initialization fail");
|
||||||
|
|
||||||
|
if (bAppend || m_pages) m_multipage=true;
|
||||||
|
m_pages++;
|
||||||
|
|
||||||
|
if (!EncodeBody(m_tif2,m_multipage,m_pages,m_pages)) cx_throw("Error saving TIFF file");
|
||||||
|
if (bAppend) {
|
||||||
|
if (!TIFFWriteDirectory(m_tif2)) cx_throw("Error saving TIFF directory");
|
||||||
|
}
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
if (m_tif2){
|
||||||
|
TIFFClose(m_tif2);
|
||||||
|
m_tif2=NULL;
|
||||||
|
m_multipage=false;
|
||||||
|
m_pages=0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!bAppend){
|
||||||
|
TIFFClose(m_tif2);
|
||||||
|
m_tif2=NULL;
|
||||||
|
m_multipage=false;
|
||||||
|
m_pages=0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
|
||||||
|
bool CxImageTIF::Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount)
|
||||||
|
{
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
if (hFile==NULL) cx_throw("invalid file pointer");
|
||||||
|
if (pImages==NULL || pagecount<=0) cx_throw("multipage TIFF, no images!");
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
for (i=0; i<pagecount; i++){
|
||||||
|
if (pImages[i]==NULL)
|
||||||
|
cx_throw("Bad image pointer");
|
||||||
|
if (!(pImages[i]->IsValid()))
|
||||||
|
cx_throw("Empty image");
|
||||||
|
}
|
||||||
|
|
||||||
|
CxImageTIF ghost;
|
||||||
|
for (i=0; i<pagecount; i++){
|
||||||
|
ghost.Ghost(pImages[i]);
|
||||||
|
if (!ghost.Encode(hFile,true)) cx_throw("Error saving TIFF file");
|
||||||
|
}
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int32_t page, int32_t pagecount)
|
||||||
|
{
|
||||||
|
uint32 height=head.biHeight;
|
||||||
|
uint32 width=head.biWidth;
|
||||||
|
uint16 bitcount=head.biBitCount;
|
||||||
|
uint16 bitspersample;
|
||||||
|
uint16 samplesperpixel;
|
||||||
|
uint16 photometric=0;
|
||||||
|
uint16 compression;
|
||||||
|
// uint16 pitch;
|
||||||
|
// int32_t line;
|
||||||
|
uint32 x, y;
|
||||||
|
|
||||||
|
samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (uint8_t)3 : (uint8_t)1;
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (bitcount==24 && AlphaIsValid()) { bitcount=32; samplesperpixel=4; }
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
bitspersample = bitcount / samplesperpixel;
|
||||||
|
|
||||||
|
//set the PHOTOMETRIC tag
|
||||||
|
RGBQUAD *rgb = GetPalette();
|
||||||
|
switch (bitcount) {
|
||||||
|
case 1:
|
||||||
|
if (CompareColors(&rgb[0],&rgb[1])<0) {
|
||||||
|
/* <abe> some viewers do not handle PHOTOMETRIC_MINISBLACK:
|
||||||
|
* let's transform the image in PHOTOMETRIC_MINISWHITE
|
||||||
|
*/
|
||||||
|
//invert the colors
|
||||||
|
RGBQUAD tempRGB=GetPaletteColor(0);
|
||||||
|
SetPaletteColor(0,GetPaletteColor(1));
|
||||||
|
SetPaletteColor(1,tempRGB);
|
||||||
|
//invert the pixels
|
||||||
|
uint8_t *iSrc=info.pImage;
|
||||||
|
for (uint32_t i=0;i<head.biSizeImage;i++){
|
||||||
|
*iSrc=(uint8_t)~(*(iSrc));
|
||||||
|
iSrc++;
|
||||||
|
}
|
||||||
|
photometric = PHOTOMETRIC_MINISWHITE;
|
||||||
|
//photometric = PHOTOMETRIC_MINISBLACK;
|
||||||
|
} else {
|
||||||
|
photometric = PHOTOMETRIC_MINISWHITE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: // Check if the DIB has a color or a greyscale palette
|
||||||
|
case 8:
|
||||||
|
photometric = PHOTOMETRIC_MINISBLACK; //default to gray scale
|
||||||
|
for (x = 0; x < head.biClrUsed; x++) {
|
||||||
|
if ((rgb->rgbRed != x)||(rgb->rgbRed != rgb->rgbGreen)||(rgb->rgbRed != rgb->rgbBlue)){
|
||||||
|
photometric = PHOTOMETRIC_PALETTE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rgb++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
case 32:
|
||||||
|
photometric = PHOTOMETRIC_RGB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
if (AlphaIsValid() && bitcount==8) samplesperpixel=2; //8bpp + alpha layer
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
|
||||||
|
// line = CalculateLine(width, bitspersample * samplesperpixel);
|
||||||
|
// pitch = (uint16)CalculatePitch(line);
|
||||||
|
|
||||||
|
//prepare the palette struct
|
||||||
|
RGBQUAD pal[256];
|
||||||
|
if (GetPalette()){
|
||||||
|
uint8_t b;
|
||||||
|
memcpy(pal,GetPalette(),GetPaletteSize());
|
||||||
|
for(uint16_t a=0;a<head.biClrUsed;a++){ //swap blue and red components
|
||||||
|
b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle standard width/height/bpp stuff
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||||
|
|
||||||
|
uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1); //<REC> gives better compression
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
|
||||||
|
|
||||||
|
// handle metrics
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)info.xDPI);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)info.yDPI);
|
||||||
|
// TIFFSetField(m_tif, TIFFTAG_XPOSITION, (float)info.xOffset);
|
||||||
|
// TIFFSetField(m_tif, TIFFTAG_YPOSITION, (float)info.yOffset);
|
||||||
|
|
||||||
|
// multi-paging - Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
|
||||||
|
if (multipage)
|
||||||
|
{
|
||||||
|
char page_number[20];
|
||||||
|
sprintf(page_number, "Page %d", page);
|
||||||
|
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page,pagecount);
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number);
|
||||||
|
} else {
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// palettes (image colormaps are automatically scaled to 16-bits)
|
||||||
|
if (photometric == PHOTOMETRIC_PALETTE) {
|
||||||
|
uint16 *r, *g, *b;
|
||||||
|
r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256);
|
||||||
|
g = r + 256;
|
||||||
|
b = g + 256;
|
||||||
|
|
||||||
|
for (int32_t i = 255; i >= 0; i--) {
|
||||||
|
b[i] = (uint16)SCALE((uint16)pal[i].rgbRed);
|
||||||
|
g[i] = (uint16)SCALE((uint16)pal[i].rgbGreen);
|
||||||
|
r[i] = (uint16)SCALE((uint16)pal[i].rgbBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b);
|
||||||
|
_TIFFfree(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compression
|
||||||
|
if (GetCodecOption(CXIMAGE_FORMAT_TIF)) {
|
||||||
|
compression = (uint16_t)GetCodecOption(CXIMAGE_FORMAT_TIF);
|
||||||
|
} else {
|
||||||
|
switch (bitcount) {
|
||||||
|
case 1 :
|
||||||
|
compression = COMPRESSION_CCITTFAX4;
|
||||||
|
break;
|
||||||
|
case 4 :
|
||||||
|
case 8 :
|
||||||
|
compression = COMPRESSION_LZW;
|
||||||
|
break;
|
||||||
|
case 24 :
|
||||||
|
case 32 :
|
||||||
|
compression = COMPRESSION_JPEG;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
compression = COMPRESSION_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);
|
||||||
|
|
||||||
|
switch (compression) {
|
||||||
|
case COMPRESSION_JPEG:
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, GetJpegQuality());
|
||||||
|
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, ((7+rowsperstrip)>>3)<<3);
|
||||||
|
break;
|
||||||
|
case COMPRESSION_LZW:
|
||||||
|
if (bitcount>=8) TIFFSetField(m_tif, TIFFTAG_PREDICTOR, 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the DIB lines from bottom to top and save them in the TIF
|
||||||
|
|
||||||
|
uint8_t *bits;
|
||||||
|
switch(bitcount) {
|
||||||
|
case 1 :
|
||||||
|
case 4 :
|
||||||
|
case 8 :
|
||||||
|
{
|
||||||
|
if (samplesperpixel==1){
|
||||||
|
bits = (uint8_t*)malloc(info.dwEffWidth);
|
||||||
|
if (!bits) return false;
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
memcpy(bits,info.pImage + (height - y - 1)*info.dwEffWidth,info.dwEffWidth);
|
||||||
|
if (TIFFWriteScanline(m_tif,bits, y, 0)==-1){
|
||||||
|
free(bits);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(bits);
|
||||||
|
}
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
else { //8bpp + alpha layer
|
||||||
|
bits = (uint8_t*)malloc(2*width);
|
||||||
|
if (!bits) return false;
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
for (x=0;x<width;x++){
|
||||||
|
bits[2*x]=BlindGetPixelIndex(x,height - y - 1);
|
||||||
|
bits[2*x+1]=AlphaGet(x,height - y - 1);
|
||||||
|
}
|
||||||
|
if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) {
|
||||||
|
free(bits);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(bits);
|
||||||
|
}
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24:
|
||||||
|
{
|
||||||
|
uint8_t *buffer = (uint8_t *)malloc(info.dwEffWidth);
|
||||||
|
if (!buffer) return false;
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
// get a pointer to the scanline
|
||||||
|
memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
|
||||||
|
// TIFFs store color data RGB instead of BGR
|
||||||
|
uint8_t *pBuf = buffer;
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
uint8_t tmp = pBuf[0];
|
||||||
|
pBuf[0] = pBuf[2];
|
||||||
|
pBuf[2] = tmp;
|
||||||
|
pBuf += 3;
|
||||||
|
}
|
||||||
|
// write the scanline to disc
|
||||||
|
if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 32 :
|
||||||
|
{
|
||||||
|
#if CXIMAGE_SUPPORT_ALPHA
|
||||||
|
uint8_t *buffer = (uint8_t *)malloc((info.dwEffWidth*4)/3);
|
||||||
|
if (!buffer) return false;
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
// get a pointer to the scanline
|
||||||
|
memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
|
||||||
|
// TIFFs store color data RGB instead of BGR
|
||||||
|
uint8_t *pSrc = buffer + 3 * width;
|
||||||
|
uint8_t *pDst = buffer + 4 * width;
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
pDst-=4;
|
||||||
|
pSrc-=3;
|
||||||
|
pDst[3] = AlphaGet(width-x-1,height-y-1);
|
||||||
|
pDst[2] = pSrc[0];
|
||||||
|
pDst[1] = pSrc[1];
|
||||||
|
pDst[0] = pSrc[2];
|
||||||
|
}
|
||||||
|
// write the scanline to disc
|
||||||
|
if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
|
||||||
|
free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buffer);
|
||||||
|
#endif //CXIMAGE_SUPPORT_ALPHA
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageTIF::TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int32_t outskew, int32_t inskew)
|
||||||
|
{
|
||||||
|
while (rows-- > 0) {
|
||||||
|
uint32 j = cols;
|
||||||
|
while (j-- > 0)
|
||||||
|
*out++ = *in++;
|
||||||
|
out += outskew;
|
||||||
|
in += inskew;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
TIFF* CxImageTIF::TIFFOpenEx(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (hFile) return _TIFFOpenEx(hFile, "rb");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageTIF::TIFFCloseEx(TIFF* tif)
|
||||||
|
{
|
||||||
|
if (tif) TIFFClose(tif);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageTIF::MoveBits( uint8_t* dest, uint8_t* from, int32_t count, int32_t bpp )
|
||||||
|
{ int32_t offbits = 0;
|
||||||
|
uint16 w;
|
||||||
|
uint32 d;
|
||||||
|
if (bpp <= 8) {
|
||||||
|
while (count-- > 0) {
|
||||||
|
if (offbits + bpp <= 8)
|
||||||
|
w = *from >> (8 - offbits - bpp);
|
||||||
|
else {
|
||||||
|
w = *from++ << (offbits + bpp - 8);
|
||||||
|
w |= *from >> (16 - offbits - bpp);
|
||||||
|
}
|
||||||
|
offbits += bpp;
|
||||||
|
if (offbits >= 8) {
|
||||||
|
offbits -= 8;
|
||||||
|
if (offbits == 0) from++;
|
||||||
|
}
|
||||||
|
*dest++ = (uint8_t)w & ((1 << bpp)-1);
|
||||||
|
}
|
||||||
|
} else if (bpp < 16) {
|
||||||
|
while (count-- > 0) {
|
||||||
|
d = (*from << 24) | (from[1]<<16) | (from[2]<<8) | from[3];
|
||||||
|
d >>= (24 - offbits);
|
||||||
|
*dest++ = (uint8_t) ( d );
|
||||||
|
offbits += bpp;
|
||||||
|
while (offbits >= 8) {
|
||||||
|
from++;
|
||||||
|
offbits -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (bpp < 32) {
|
||||||
|
while (count-- > 0) {
|
||||||
|
d = (*from << 24) | (from[1]<<16) | (from[2]<<8) | from[3];
|
||||||
|
//d = *(uint32*)from;
|
||||||
|
*dest++ = (uint8_t) ( d >> (offbits + bpp - 8) );
|
||||||
|
offbits += bpp;
|
||||||
|
while (offbits >= 8) {
|
||||||
|
from++;
|
||||||
|
offbits -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (count-- > 0) {
|
||||||
|
d = *(uint32*)from;
|
||||||
|
*dest++ = (uint8_t) (d >> 24);
|
||||||
|
from += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void CxImageTIF::MoveBitsPal( uint8_t* dest, uint8_t*from, int32_t count, int32_t bpp, RGBQUAD* pal )
|
||||||
|
{ int32_t offbits = 0;
|
||||||
|
uint32 d;
|
||||||
|
uint16 palidx;
|
||||||
|
while (count-- > 0) {
|
||||||
|
d = (*from << 24) | ( *( from + 1 ) << 16 )
|
||||||
|
| ( *( from + 2 ) << 8 )
|
||||||
|
| ( *( from + 3 ) );
|
||||||
|
palidx = (uint16) (d >> (32 - offbits - bpp));
|
||||||
|
if (bpp < 16) {
|
||||||
|
palidx <<= 16-bpp;
|
||||||
|
palidx = (palidx >> 8) | (palidx <<8);
|
||||||
|
palidx >>= 16-bpp;
|
||||||
|
} else palidx = (palidx >> 8) | (palidx << 8);
|
||||||
|
*dest++ = pal[palidx].rgbBlue;
|
||||||
|
*dest++ = pal[palidx].rgbGreen;
|
||||||
|
*dest++ = pal[palidx].rgbRed;
|
||||||
|
offbits += bpp;
|
||||||
|
while (offbits >= 8) {
|
||||||
|
from++;
|
||||||
|
offbits -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#endif // CXIMAGE_SUPPORT_TIF
|
||||||
62
Raw2Bmp_MFC/include/ximatif.h
Normal file
62
Raw2Bmp_MFC/include/ximatif.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* File: ximatif.h
|
||||||
|
* Purpose: TIFF Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageTIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
*
|
||||||
|
* Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
|
||||||
|
*
|
||||||
|
* Special thanks to Abe <God(dot)bless(at)marihuana(dot)com> for MultiPageTIFF code.
|
||||||
|
*
|
||||||
|
* LibTIFF is:
|
||||||
|
* Copyright (c) 1988-1997 Sam Leffler
|
||||||
|
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__ximatif_h)
|
||||||
|
#define __ximatif_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_TIF
|
||||||
|
|
||||||
|
#include "../tiff/tiffio.h"
|
||||||
|
|
||||||
|
class DLL_EXP CxImageTIF: public CxImage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxImageTIF(): CxImage(CXIMAGE_FORMAT_TIF) {m_tif2=NULL; m_multipage=false; m_pages=0;}
|
||||||
|
~CxImageTIF();
|
||||||
|
|
||||||
|
TIFF* TIFFOpenEx(CxFile * hFile);
|
||||||
|
void TIFFCloseEx(TIFF* tif);
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TIF);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TIF);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile, bool bAppend=false);
|
||||||
|
bool Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount);
|
||||||
|
bool Encode(FILE *hFile, bool bAppend=false) { CxIOFile file(hFile); return Encode(&file,bAppend); }
|
||||||
|
bool Encode(FILE *hFile, CxImage ** pImages, int32_t pagecount)
|
||||||
|
{ CxIOFile file(hFile); return Encode(&file, pImages, pagecount); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int32_t outskew, int32_t inskew);
|
||||||
|
bool EncodeBody(TIFF *m_tif, bool multipage=false, int32_t page=0, int32_t pagecount=0);
|
||||||
|
TIFF *m_tif2;
|
||||||
|
bool m_multipage;
|
||||||
|
int32_t m_pages;
|
||||||
|
void MoveBits( uint8_t* dest, uint8_t* from, int32_t count, int32_t bpp );
|
||||||
|
void MoveBitsPal( uint8_t* dest, uint8_t*from, int32_t count, int32_t bpp, RGBQUAD* pal );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
2728
Raw2Bmp_MFC/include/ximatran.cpp
Normal file
2728
Raw2Bmp_MFC/include/ximatran.cpp
Normal file
File diff suppressed because it is too large
Load Diff
134
Raw2Bmp_MFC/include/ximawbmp.cpp
Normal file
134
Raw2Bmp_MFC/include/ximawbmp.cpp
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* File: ximawbmp.cpp
|
||||||
|
* Purpose: Platform Independent WBMP Image Class Loader and Writer
|
||||||
|
* 12/Jul/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* CxImage version 7.0.1 07/Jan/2011
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximawbmp.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
|
||||||
|
#include "ximaiter.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageWBMP::Decode(CxFile *hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
WBMPHEADER wbmpHead;
|
||||||
|
|
||||||
|
cx_try
|
||||||
|
{
|
||||||
|
ReadOctet(hFile, &wbmpHead.Type);
|
||||||
|
|
||||||
|
uint32_t dat;
|
||||||
|
ReadOctet(hFile, &dat);
|
||||||
|
wbmpHead.FixHeader = (uint8_t)dat;
|
||||||
|
|
||||||
|
ReadOctet(hFile, &wbmpHead.ImageWidth);
|
||||||
|
ReadOctet(hFile, &wbmpHead.ImageHeight);
|
||||||
|
|
||||||
|
if (hFile->Eof())
|
||||||
|
cx_throw("Not a WBMP");
|
||||||
|
|
||||||
|
if (wbmpHead.Type != 0)
|
||||||
|
cx_throw("Unsupported WBMP type");
|
||||||
|
|
||||||
|
head.biWidth = wbmpHead.ImageWidth;
|
||||||
|
head.biHeight= wbmpHead.ImageHeight;
|
||||||
|
|
||||||
|
if (head.biWidth<=0 || head.biHeight<=0)
|
||||||
|
cx_throw("Corrupted WBMP");
|
||||||
|
|
||||||
|
if (info.nEscape == -1){
|
||||||
|
info.dwType = CXIMAGE_FORMAT_WBMP;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Create(head.biWidth, head.biHeight, 1, CXIMAGE_FORMAT_WBMP);
|
||||||
|
if (!IsValid()) cx_throw("WBMP Create failed");
|
||||||
|
SetGrayPalette();
|
||||||
|
|
||||||
|
int32_t linewidth=(head.biWidth+7)/8;
|
||||||
|
CImageIterator iter(this);
|
||||||
|
iter.Upset();
|
||||||
|
for (int32_t y=0; y < head.biHeight; y++){
|
||||||
|
hFile->Read(iter.GetRow(),linewidth,1);
|
||||||
|
iter.PrevRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
} cx_catch {
|
||||||
|
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageWBMP::ReadOctet(CxFile * hFile, uint32_t *data)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
*data = 0;
|
||||||
|
do {
|
||||||
|
if (hFile->Eof()) return false;
|
||||||
|
c = (uint8_t)hFile->GetC();
|
||||||
|
*data <<= 7;
|
||||||
|
*data |= (c & 0x7F);
|
||||||
|
} while ((c&0x80)!=0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageWBMP::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (EncodeSafeCheck(hFile)) return false;
|
||||||
|
|
||||||
|
//check format limits
|
||||||
|
if (head.biBitCount!=1){
|
||||||
|
strcpy(info.szLastError,"Can't save this image as WBMP");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WBMPHEADER wbmpHead;
|
||||||
|
wbmpHead.Type=0;
|
||||||
|
wbmpHead.FixHeader=0;
|
||||||
|
wbmpHead.ImageWidth=head.biWidth;
|
||||||
|
wbmpHead.ImageHeight=head.biHeight;
|
||||||
|
|
||||||
|
// Write the file header
|
||||||
|
hFile->PutC('\0');
|
||||||
|
hFile->PutC('\0');
|
||||||
|
WriteOctet(hFile,wbmpHead.ImageWidth);
|
||||||
|
WriteOctet(hFile,wbmpHead.ImageHeight);
|
||||||
|
// Write the pixels
|
||||||
|
int32_t linewidth=(wbmpHead.ImageWidth+7)/8;
|
||||||
|
CImageIterator iter(this);
|
||||||
|
iter.Upset();
|
||||||
|
for (uint32_t y=0; y < wbmpHead.ImageHeight; y++){
|
||||||
|
hFile->Write(iter.GetRow(),linewidth,1);
|
||||||
|
iter.PrevRow();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageWBMP::WriteOctet(CxFile * hFile, const uint32_t data)
|
||||||
|
{
|
||||||
|
int32_t ns = 0;
|
||||||
|
while (data>>(ns+7)) ns+=7;
|
||||||
|
while (ns>0){
|
||||||
|
if (!hFile->PutC(0x80 | (uint8_t)(data>>ns))) return false;
|
||||||
|
ns-=7;
|
||||||
|
}
|
||||||
|
if (!(hFile->PutC((uint8_t)(0x7F & data)))) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // CXIMAGE_SUPPORT_WBMP
|
||||||
|
|
||||||
49
Raw2Bmp_MFC/include/ximawbmp.h
Normal file
49
Raw2Bmp_MFC/include/ximawbmp.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* File: ximawbmp.h
|
||||||
|
* Purpose: WBMP Image Class Loader and Writer
|
||||||
|
*/
|
||||||
|
/* ==========================================================
|
||||||
|
* CxImageWBMP (c) 12/Jul/2002 Davide Pizzolato - www.xdp.it
|
||||||
|
* For conditions of distribution and use, see copyright notice in ximage.h
|
||||||
|
* ==========================================================
|
||||||
|
*/
|
||||||
|
#if !defined(__ximaWBMP_h)
|
||||||
|
#define __ximaWBMP_h
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_WBMP
|
||||||
|
|
||||||
|
class CxImageWBMP: public CxImage
|
||||||
|
{
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct tagWbmpHeader
|
||||||
|
{
|
||||||
|
uint32_t Type; // 0
|
||||||
|
uint8_t FixHeader; // 0
|
||||||
|
uint32_t ImageWidth; // Image Width
|
||||||
|
uint32_t ImageHeight; // Image Height
|
||||||
|
} WBMPHEADER;
|
||||||
|
#pragma pack()
|
||||||
|
public:
|
||||||
|
CxImageWBMP(): CxImage(CXIMAGE_FORMAT_WBMP) {}
|
||||||
|
|
||||||
|
// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_WBMP);}
|
||||||
|
// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_WBMP);}
|
||||||
|
bool Decode(CxFile * hFile);
|
||||||
|
bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
|
||||||
|
protected:
|
||||||
|
bool ReadOctet(CxFile * hFile, uint32_t *data);
|
||||||
|
|
||||||
|
public:
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
protected:
|
||||||
|
bool WriteOctet(CxFile * hFile, const uint32_t data);
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
483
Raw2Bmp_MFC/include/ximawmf.cpp
Normal file
483
Raw2Bmp_MFC/include/ximawmf.cpp
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
/*
|
||||||
|
*********************************************************************
|
||||||
|
* File: ximawmf.cpp
|
||||||
|
* Purpose: Windows Metafile Class Loader and Writer
|
||||||
|
* Author: Volker Horch - vhorch@gmx.de
|
||||||
|
* created: 13-Jun-2002
|
||||||
|
*
|
||||||
|
* Note: If the code below works, i wrote it.
|
||||||
|
* If it doesn't work, i don't know who wrote it.
|
||||||
|
*********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*********************************************************************
|
||||||
|
Note by Author:
|
||||||
|
*********************************************************************
|
||||||
|
|
||||||
|
Metafile Formats:
|
||||||
|
=================
|
||||||
|
|
||||||
|
There are 2 kinds of Windows Metafiles:
|
||||||
|
- Standard Windows Metafile
|
||||||
|
- Placeable Windows Metafile
|
||||||
|
|
||||||
|
A StandardWindows Metafile looks like:
|
||||||
|
- Metafile Header (MEATAHEADER)
|
||||||
|
- Metafile Records
|
||||||
|
|
||||||
|
A Placeable Metafile looks like:
|
||||||
|
- Aldus Header (METAFILEHEADER)
|
||||||
|
- Metafile Header (METAHEADER)
|
||||||
|
- Metafile Records
|
||||||
|
|
||||||
|
The "Metafile Header" and the "Metafile Records" are the same
|
||||||
|
for both formats. However, the Standard Metafile does not contain any
|
||||||
|
information about the original dimensions or x/y ratio of the Metafile.
|
||||||
|
|
||||||
|
I decided, to allow only placeable Metafiles here. If you also want to
|
||||||
|
enable Standard Metafiles, you will have to guess the dimensions of
|
||||||
|
the image.
|
||||||
|
|
||||||
|
*********************************************************************
|
||||||
|
Limitations: see ximawmf.h
|
||||||
|
you may configure some stuff there
|
||||||
|
*********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ximawmf.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageWMF::Decode(CxFile *hFile, int32_t nForceWidth, int32_t nForceHeight)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
|
||||||
|
HENHMETAFILE hMeta;
|
||||||
|
HDC hDC;
|
||||||
|
int32_t cx,cy;
|
||||||
|
|
||||||
|
//save the current position of the file
|
||||||
|
int32_t pos = hFile->Tell();
|
||||||
|
|
||||||
|
// Read the Metafile and convert to an Enhanced Metafile
|
||||||
|
METAFILEHEADER mfh;
|
||||||
|
hMeta = ConvertWmfFiletoEmf(hFile, &mfh);
|
||||||
|
if (hMeta) { // ok, it's a WMF
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// We use the original WMF size information, because conversion to
|
||||||
|
// EMF adjusts the Metafile to Full Screen or does not set rclBounds at all
|
||||||
|
// ENHMETAHEADER emh;
|
||||||
|
// uint32_t uRet;
|
||||||
|
// uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
|
||||||
|
// sizeof(ENHMETAHEADER), // size of buffer, in bytes
|
||||||
|
// &emh); // address of buffer to receive data
|
||||||
|
// if (!uRet){
|
||||||
|
// DeleteEnhMetaFile(hMeta);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// // calculate size
|
||||||
|
// cx = emh.rclBounds.right - emh.rclBounds.left;
|
||||||
|
// cy = emh.rclBounds.bottom - emh.rclBounds.top;
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// calculate size
|
||||||
|
// scale the metafile (pixels/inch of metafile => pixels/inch of display)
|
||||||
|
// mfh.inch already checked to be <> 0
|
||||||
|
|
||||||
|
hDC = ::GetDC(0);
|
||||||
|
int32_t cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||||
|
int32_t cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||||
|
::ReleaseDC(0, hDC);
|
||||||
|
|
||||||
|
cx = (mfh.inch/2 + (mfh.bbox.right - mfh.bbox.left) * cx1) / mfh.inch;
|
||||||
|
cy = (mfh.inch/2 + (mfh.bbox.bottom - mfh.bbox.top) * cy1) / mfh.inch;
|
||||||
|
|
||||||
|
} else { // maybe it's an EMF...
|
||||||
|
|
||||||
|
hFile->Seek(pos,SEEK_SET);
|
||||||
|
|
||||||
|
ENHMETAHEADER emh;
|
||||||
|
hMeta = ConvertEmfFiletoEmf(hFile, &emh);
|
||||||
|
|
||||||
|
if (!hMeta){
|
||||||
|
strcpy(info.szLastError,"corrupted WMF");
|
||||||
|
return false; // definitively give up
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, it's an EMF; calculate canvas size
|
||||||
|
cx = emh.rclBounds.right - emh.rclBounds.left;
|
||||||
|
cy = emh.rclBounds.bottom - emh.rclBounds.top;
|
||||||
|
|
||||||
|
// alternative methods, sometime not so reliable... [DP]
|
||||||
|
//cx = emh.szlDevice.cx;
|
||||||
|
//cy = emh.szlDevice.cy;
|
||||||
|
//
|
||||||
|
//hDC = ::GetDC(0);
|
||||||
|
//float hscale = (float)GetDeviceCaps(hDC, HORZRES)/(100.0f * GetDeviceCaps(hDC, HORZSIZE));
|
||||||
|
//float vscale = (float)GetDeviceCaps(hDC, VERTRES)/(100.0f * GetDeviceCaps(hDC, VERTSIZE));
|
||||||
|
//::ReleaseDC(0, hDC);
|
||||||
|
//cx = (int32_t)((emh.rclFrame.right - emh.rclFrame.left) * hscale);
|
||||||
|
//cy = (int32_t)((emh.rclFrame.bottom - emh.rclFrame.top) * vscale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.nEscape == -1) { // Check if cancelled
|
||||||
|
head.biWidth = cx;
|
||||||
|
head.biHeight= cy;
|
||||||
|
info.dwType = CXIMAGE_FORMAT_WMF;
|
||||||
|
DeleteEnhMetaFile(hMeta);
|
||||||
|
strcpy(info.szLastError,"output dimensions returned");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cx || !cy) {
|
||||||
|
DeleteEnhMetaFile(hMeta);
|
||||||
|
strcpy(info.szLastError,"empty WMF");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nForceWidth) cx=nForceWidth;
|
||||||
|
if (nForceHeight) cy=nForceHeight;
|
||||||
|
ShrinkMetafile(cx, cy); // !! Otherwise Bitmap may have bombastic size
|
||||||
|
|
||||||
|
HDC hDC0 = ::GetDC(0); // DC of screen
|
||||||
|
HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy); // has # colors of display
|
||||||
|
hDC = CreateCompatibleDC(hDC0); // memory dc compatible with screen
|
||||||
|
::ReleaseDC(0, hDC0); // don't need anymore. get rid of it.
|
||||||
|
|
||||||
|
if (hDC){
|
||||||
|
if (hBitmap){
|
||||||
|
RECT rc = {0,0,cx,cy};
|
||||||
|
int32_t bpp = ::GetDeviceCaps(hDC, BITSPIXEL);
|
||||||
|
|
||||||
|
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);
|
||||||
|
|
||||||
|
// clear out the entire bitmap with windows background
|
||||||
|
// because the MetaFile may not contain background information
|
||||||
|
uint32_t dwBack = XMF_COLOR_BACK;
|
||||||
|
#if XMF_SUPPORT_TRANSPARENCY
|
||||||
|
if (bpp == 24) dwBack = XMF_COLOR_TRANSPARENT;
|
||||||
|
#endif
|
||||||
|
uint32_t OldColor = SetBkColor(hDC, dwBack);
|
||||||
|
ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
|
||||||
|
SetBkColor(hDC, OldColor);
|
||||||
|
|
||||||
|
//retrieves optional palette entries from the specified enhanced metafile
|
||||||
|
PLOGPALETTE plogPal;
|
||||||
|
PBYTE pjTmp;
|
||||||
|
HPALETTE hPal;
|
||||||
|
int32_t iEntries = GetEnhMetaFilePaletteEntries(hMeta, 0, NULL);
|
||||||
|
if (iEntries) {
|
||||||
|
if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
|
||||||
|
sizeof(uint32_t) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
DeleteDC(hDC);
|
||||||
|
DeleteEnhMetaFile(hMeta);
|
||||||
|
strcpy(info.szLastError,"Cancelled");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
plogPal->palVersion = 0x300;
|
||||||
|
plogPal->palNumEntries = (uint16_t) iEntries;
|
||||||
|
pjTmp = (PBYTE) plogPal;
|
||||||
|
pjTmp += 4;
|
||||||
|
|
||||||
|
GetEnhMetaFilePaletteEntries(hMeta, iEntries, (PPALETTEENTRY)pjTmp);
|
||||||
|
hPal = CreatePalette(plogPal);
|
||||||
|
GlobalFree(plogPal);
|
||||||
|
|
||||||
|
SelectPalette(hDC, hPal, FALSE);
|
||||||
|
RealizePalette(hDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play the Metafile into Memory DC
|
||||||
|
BOOL bRet = PlayEnhMetaFile(hDC, // handle to a device context
|
||||||
|
hMeta, // handle to an enhanced metafile
|
||||||
|
&rc); // pointer to bounding rectangle
|
||||||
|
|
||||||
|
SelectObject(hDC, hBitmapOld);
|
||||||
|
DeleteEnhMetaFile(hMeta); // we are done with this one
|
||||||
|
|
||||||
|
if (info.nEscape) { // Check if cancelled
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
DeleteDC(hDC);
|
||||||
|
strcpy(info.szLastError,"Cancelled");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the Bitmap now has the image.
|
||||||
|
// Create our DIB and convert the DDB into DIB
|
||||||
|
if (!Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)) {
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
DeleteDC(hDC);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if XMF_SUPPORT_TRANSPARENCY
|
||||||
|
if (bpp == 24) {
|
||||||
|
RGBQUAD rgbTrans = { XMF_RGBQUAD_TRANSPARENT };
|
||||||
|
SetTransColor(rgbTrans);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// We're finally ready to get the DIB. Call the driver and let
|
||||||
|
// it party on our bitmap. It will fill in the color table,
|
||||||
|
// and bitmap bits of our global memory block.
|
||||||
|
bRet = GetDIBits(hDC, hBitmap, 0,
|
||||||
|
(uint32_t)cy, GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
|
||||||
|
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
DeleteDC(hDC);
|
||||||
|
|
||||||
|
return (bRet!=0);
|
||||||
|
} else {
|
||||||
|
DeleteDC(hDC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hBitmap) DeleteObject(hBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteEnhMetaFile(hMeta);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Function: CheckMetafileHeader
|
||||||
|
Purpose: Check if the Metafileheader of a file is valid
|
||||||
|
**********************************************************************/
|
||||||
|
BOOL CxImageWMF::CheckMetafileHeader(METAFILEHEADER *metafileheader)
|
||||||
|
{
|
||||||
|
uint16_t *pw;
|
||||||
|
uint16_t cs;
|
||||||
|
int32_t i;
|
||||||
|
|
||||||
|
// check magic #
|
||||||
|
if (metafileheader->key != 0x9ac6cdd7L) return false;
|
||||||
|
|
||||||
|
// test checksum of header
|
||||||
|
pw = (uint16_t *)metafileheader;
|
||||||
|
cs = *pw;
|
||||||
|
pw++;
|
||||||
|
for (i = 0; i < 9; i++) {
|
||||||
|
cs ^= *pw;
|
||||||
|
pw++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs != metafileheader->checksum) return false;
|
||||||
|
|
||||||
|
// check resolution
|
||||||
|
if ((metafileheader->inch <= 0) || (metafileheader->inch > 2540)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Function: ConvertWmfFiletoEmf
|
||||||
|
Purpose: Converts a Windows Metafile into an Enhanced Metafile
|
||||||
|
**********************************************************************/
|
||||||
|
HENHMETAFILE CxImageWMF::ConvertWmfFiletoEmf(CxFile *fp, METAFILEHEADER *metafileheader)
|
||||||
|
{
|
||||||
|
HENHMETAFILE hMeta;
|
||||||
|
uint32_t lenFile;
|
||||||
|
uint32_t len;
|
||||||
|
uint8_t *p;
|
||||||
|
METAHEADER mfHeader;
|
||||||
|
uint32_t seekpos;
|
||||||
|
|
||||||
|
hMeta = 0;
|
||||||
|
|
||||||
|
// get length of the file
|
||||||
|
lenFile = fp->Size();
|
||||||
|
|
||||||
|
// a placeable metafile starts with a METAFILEHEADER
|
||||||
|
// read it and check metafileheader
|
||||||
|
len = fp->Read(metafileheader, 1, sizeof(METAFILEHEADER));
|
||||||
|
if (len < sizeof(METAFILEHEADER)) return (hMeta);
|
||||||
|
|
||||||
|
if (CheckMetafileHeader(metafileheader)) {
|
||||||
|
// This is a placeable metafile
|
||||||
|
// Convert the placeable format into something that can
|
||||||
|
// be used with GDI metafile functions
|
||||||
|
seekpos = sizeof(METAFILEHEADER);
|
||||||
|
} else {
|
||||||
|
// Not a placeable wmf. A windows metafile?
|
||||||
|
// at least not scaleable.
|
||||||
|
// we could try to convert, but would loose ratio. don't allow this
|
||||||
|
return (hMeta);
|
||||||
|
|
||||||
|
//metafileheader->bbox.right = ?;
|
||||||
|
//metafileheader->bbox.left = ?;
|
||||||
|
//metafileheader->bbox.bottom = ?;
|
||||||
|
//metafileheader->bbox.top = ?;
|
||||||
|
//metafileheader->inch = ?;
|
||||||
|
//
|
||||||
|
//seekpos = 0;
|
||||||
|
// fp->Seek(0, SEEK_SET); // rewind
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we have a metaheader regardless of whether
|
||||||
|
// the metafile was a windows metafile or a placeable metafile
|
||||||
|
// so check to see if it is valid. There is really no good
|
||||||
|
// way to do this so just make sure that the mtType is either
|
||||||
|
// 1 or 2 (memory or disk file)
|
||||||
|
// in addition we compare the length of the METAHEADER against
|
||||||
|
// the length of the file. if filelength < len => no Metafile
|
||||||
|
|
||||||
|
len = fp->Read(&mfHeader, 1, sizeof(METAHEADER));
|
||||||
|
if (len < sizeof(METAHEADER)) return (hMeta);
|
||||||
|
|
||||||
|
if ((mfHeader.mtType != 1) && (mfHeader.mtType != 2)) return (hMeta);
|
||||||
|
|
||||||
|
// Length in Bytes from METAHEADER
|
||||||
|
len = mfHeader.mtSize * 2;
|
||||||
|
if (len > lenFile) return (hMeta);
|
||||||
|
|
||||||
|
// Allocate memory for the metafile bits
|
||||||
|
p = (uint8_t *)malloc(len);
|
||||||
|
if (!p) return (hMeta);
|
||||||
|
|
||||||
|
// seek back to METAHEADER and read all the stuff at once
|
||||||
|
fp->Seek(seekpos, SEEK_SET);
|
||||||
|
lenFile = fp->Read(p, 1, len);
|
||||||
|
if (lenFile != len) {
|
||||||
|
free(p);
|
||||||
|
return (hMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following (commented code) works, but adjusts rclBound of the
|
||||||
|
// Enhanced Metafile to full screen.
|
||||||
|
// the METAFILEHEADER from above is needed to scale the image
|
||||||
|
|
||||||
|
// hMeta = SetWinMetaFileBits(len, p, NULL, NULL);
|
||||||
|
|
||||||
|
// scale the metafile (pixels/inch of metafile => pixels/inch of display)
|
||||||
|
|
||||||
|
METAFILEPICT mfp;
|
||||||
|
int32_t cx1, cy1;
|
||||||
|
HDC hDC;
|
||||||
|
|
||||||
|
hDC = ::GetDC(0);
|
||||||
|
cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
||||||
|
cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
||||||
|
|
||||||
|
memset(&mfp, 0, sizeof(mfp));
|
||||||
|
|
||||||
|
mfp.mm = MM_ANISOTROPIC;
|
||||||
|
mfp.xExt = 10000; //(metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch;
|
||||||
|
mfp.yExt = 10000; //(metafileheader->bbox.bottom - metafileheader->bbox.top) * cy1 / metafileheader->inch;
|
||||||
|
mfp.hMF = 0;
|
||||||
|
|
||||||
|
// in MM_ANISOTROPIC mode xExt and yExt are in MM_HIENGLISH
|
||||||
|
// MM_HIENGLISH means: Each logical unit is converted to 0.001 inch
|
||||||
|
//mfp.xExt *= 1000;
|
||||||
|
//mfp.yExt *= 1000;
|
||||||
|
// ????
|
||||||
|
//int32_t k = 332800 / ::GetSystemMetrics(SM_CXSCREEN);
|
||||||
|
//mfp.xExt *= k; mfp.yExt *= k;
|
||||||
|
|
||||||
|
// fix for Win9x
|
||||||
|
while ((mfp.xExt < 6554) && (mfp.yExt < 6554))
|
||||||
|
{
|
||||||
|
mfp.xExt *= 10;
|
||||||
|
mfp.yExt *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
|
||||||
|
|
||||||
|
if (!hMeta){ //try 2nd conversion using a different mapping
|
||||||
|
mfp.mm = MM_TEXT;
|
||||||
|
hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
|
||||||
|
}
|
||||||
|
|
||||||
|
::ReleaseDC(0, hDC);
|
||||||
|
|
||||||
|
// Free Memory
|
||||||
|
free(p);
|
||||||
|
|
||||||
|
return (hMeta);
|
||||||
|
}
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
HENHMETAFILE CxImageWMF::ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh)
|
||||||
|
{
|
||||||
|
HENHMETAFILE hMeta;
|
||||||
|
int32_t iLen = pFile->Size();
|
||||||
|
|
||||||
|
// Check the header first: <km>
|
||||||
|
int32_t pos = pFile->Tell();
|
||||||
|
int32_t iLenRead = pFile->Read(pemfh, 1, sizeof(ENHMETAHEADER));
|
||||||
|
if (iLenRead < sizeof(ENHMETAHEADER)) return NULL;
|
||||||
|
if (pemfh->iType != EMR_HEADER) return NULL;
|
||||||
|
if (pemfh->dSignature != ENHMETA_SIGNATURE) return NULL;
|
||||||
|
//if (pemfh->nBytes != (uint32_t)iLen) return NULL;
|
||||||
|
pFile->Seek(pos,SEEK_SET);
|
||||||
|
|
||||||
|
uint8_t* pBuff = (uint8_t *)malloc(iLen);
|
||||||
|
if (!pBuff) return (FALSE);
|
||||||
|
|
||||||
|
// Read the Enhanced Metafile
|
||||||
|
iLenRead = pFile->Read(pBuff, 1, iLen);
|
||||||
|
if (iLenRead != iLen) {
|
||||||
|
free(pBuff);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make it a Memory Metafile
|
||||||
|
hMeta = SetEnhMetaFileBits(iLen, pBuff);
|
||||||
|
|
||||||
|
free(pBuff); // finished with this one
|
||||||
|
|
||||||
|
if (!hMeta) return NULL; // oops.
|
||||||
|
|
||||||
|
// Get the Enhanced Metafile Header
|
||||||
|
uint32_t uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
|
||||||
|
sizeof(ENHMETAHEADER), // size of buffer, in bytes
|
||||||
|
pemfh); // address of buffer to receive data
|
||||||
|
|
||||||
|
if (!uRet) {
|
||||||
|
DeleteEnhMetaFile(hMeta);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hMeta);
|
||||||
|
}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif //CXIMAGE_SUPPORT_DECODE
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
bool CxImageWMF::Encode(CxFile * hFile)
|
||||||
|
{
|
||||||
|
if (hFile == NULL) return false;
|
||||||
|
strcpy(info.szLastError, "Save WMF not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
Function: ShrinkMetafile
|
||||||
|
Purpose: Shrink the size of a metafile to be not larger than
|
||||||
|
the definition
|
||||||
|
**********************************************************************/
|
||||||
|
void CxImageWMF::ShrinkMetafile(int32_t &cx, int32_t &cy)
|
||||||
|
{
|
||||||
|
int32_t xScreen = XMF_MAXSIZE_CX;
|
||||||
|
int32_t yScreen = XMF_MAXSIZE_CY;
|
||||||
|
|
||||||
|
if (cx > xScreen){
|
||||||
|
cy = cy * xScreen / cx;
|
||||||
|
cx = xScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cy > yScreen){
|
||||||
|
cx = cx * yScreen / cy;
|
||||||
|
cy = yScreen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CIMAGE_SUPPORT_WMF
|
||||||
|
|
||||||
154
Raw2Bmp_MFC/include/ximawmf.h
Normal file
154
Raw2Bmp_MFC/include/ximawmf.h
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
*********************************************************************
|
||||||
|
* File: ximawmf.h
|
||||||
|
* Purpose: Windows Metafile Class Loader and Writer
|
||||||
|
* Author: Volker Horch - vhorch@gmx.de
|
||||||
|
* created: 13-Jun-2002
|
||||||
|
*********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*********************************************************************
|
||||||
|
Notes by Author:
|
||||||
|
*********************************************************************
|
||||||
|
|
||||||
|
Limitations:
|
||||||
|
============
|
||||||
|
|
||||||
|
a) Transparency:
|
||||||
|
|
||||||
|
A Metafile is vector graphics, which has transparency by design.
|
||||||
|
This class always converts into a Bitmap format. Transparency is
|
||||||
|
supported, but there is no good way to find out, which parts
|
||||||
|
of the Metafile are transparent. There are two ways how we can
|
||||||
|
handle this:
|
||||||
|
|
||||||
|
- Clear the Background of the Bitmap with the background color
|
||||||
|
you like (i have used COLOR_WINDOW) and don't support transparency.
|
||||||
|
|
||||||
|
below #define XMF_SUPPORT_TRANSPARENCY 0
|
||||||
|
#define XMF_COLOR_BACK RGB(Background color you like)
|
||||||
|
|
||||||
|
- Clear the Background of the Bitmap with a very unusual color
|
||||||
|
(which one ?) and use this color as the transparent color
|
||||||
|
|
||||||
|
below #define XMF_SUPPORT_TRANSPARENCY 1
|
||||||
|
#define XMF_COLOR_TRANSPARENT_R ...
|
||||||
|
#define XMF_COLOR_TRANSPARENT_G ...
|
||||||
|
#define XMF_COLOR_TRANSPARENT_B ...
|
||||||
|
|
||||||
|
b) Resolution
|
||||||
|
|
||||||
|
Once we have converted the Metafile into a Bitmap and we zoom in
|
||||||
|
or out, the image may not look very good. If we still had the
|
||||||
|
original Metafile, zooming would produce good results always.
|
||||||
|
|
||||||
|
c) Size
|
||||||
|
|
||||||
|
Although the filesize of a Metafile may be very small, it might
|
||||||
|
produce a Bitmap with a bombastic size. Assume you have a Metafile
|
||||||
|
with an image size of 6000*4000, which contains just one Metafile
|
||||||
|
record ((e.g. a line from (0,0) to (6000, 4000)). The filesize
|
||||||
|
of this Metafile would be let's say 100kB. If we convert it to
|
||||||
|
a 6000*4000 Bitmap with 24 Bits/Pixes, the Bitmap would consume
|
||||||
|
about 68MB of memory.
|
||||||
|
|
||||||
|
I have choosen, to limit the size of the Bitmap to max.
|
||||||
|
screensize, to avoid memory problems.
|
||||||
|
|
||||||
|
If you want something else,
|
||||||
|
modify #define XMF_MAXSIZE_CX / XMF_MAXSIZE_CY below
|
||||||
|
|
||||||
|
*********************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XIMAWMF_H
|
||||||
|
#define _XIMAWMF_H
|
||||||
|
|
||||||
|
#include "ximage.h"
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
|
||||||
|
|
||||||
|
class CxImageWMF: public CxImage
|
||||||
|
{
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct tagRECT16
|
||||||
|
{
|
||||||
|
int16_t left;
|
||||||
|
int16_t top;
|
||||||
|
int16_t right;
|
||||||
|
int16_t bottom;
|
||||||
|
} RECT16;
|
||||||
|
|
||||||
|
// taken from Windos 3.11 SDK Documentation (Programmer's Reference Volume 4: Resources)
|
||||||
|
typedef struct tagMETAFILEHEADER
|
||||||
|
{
|
||||||
|
uint32_t key; // always 0x9ac6cdd7
|
||||||
|
uint16_t reserved1; // reserved = 0
|
||||||
|
RECT16 bbox; // bounding rectangle in metafile units as defined in "inch"
|
||||||
|
uint16_t inch; // number of metafile units per inch (should be < 1440)
|
||||||
|
uint32_t reserved2; // reserved = 0
|
||||||
|
uint16_t checksum; // sum of the first 10 WORDS (using XOR operator)
|
||||||
|
} METAFILEHEADER;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
CxImageWMF(): CxImage(CXIMAGE_FORMAT_WMF) { }
|
||||||
|
|
||||||
|
bool Decode(CxFile * hFile, int32_t nForceWidth=0, int32_t nForceHeight=0);
|
||||||
|
bool Decode(FILE *hFile, int32_t nForceWidth=0, int32_t nForceHeight=0)
|
||||||
|
{ CxIOFile file(hFile); return Decode(&file,nForceWidth,nForceHeight); }
|
||||||
|
|
||||||
|
#if CXIMAGE_SUPPORT_ENCODE
|
||||||
|
bool Encode(CxFile * hFile);
|
||||||
|
bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
|
||||||
|
#endif // CXIMAGE_SUPPORT_ENCODE
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ShrinkMetafile(int32_t &cx, int32_t &cy);
|
||||||
|
BOOL CheckMetafileHeader(METAFILEHEADER *pmetafileheader);
|
||||||
|
HENHMETAFILE ConvertWmfFiletoEmf(CxFile *pFile, METAFILEHEADER *pmetafileheader);
|
||||||
|
HENHMETAFILE ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define METAFILEKEY 0x9ac6cdd7L
|
||||||
|
|
||||||
|
// Background color definition (if no transparency). see Notes above
|
||||||
|
#define XMF_COLOR_BACK GetSysColor(COLOR_WINDOW)
|
||||||
|
// alternatives
|
||||||
|
//#define XMF_COLOR_BACK RGB(192, 192, 192) // lite gray
|
||||||
|
//#define XMF_COLOR_BACK RGB( 0, 0, 0) // black
|
||||||
|
//#define XMF_COLOR_BACK RGB(255, 255, 255) // white
|
||||||
|
|
||||||
|
|
||||||
|
// transparency support. see Notes above
|
||||||
|
#define XMF_SUPPORT_TRANSPARENCY 0
|
||||||
|
#define XMF_COLOR_TRANSPARENT_R 211
|
||||||
|
#define XMF_COLOR_TRANSPARENT_G 121
|
||||||
|
#define XMF_COLOR_TRANSPARENT_B 112
|
||||||
|
// don't change
|
||||||
|
#define XMF_COLOR_TRANSPARENT RGB (XMF_COLOR_TRANSPARENT_R, \
|
||||||
|
XMF_COLOR_TRANSPARENT_G, \
|
||||||
|
XMF_COLOR_TRANSPARENT_B)
|
||||||
|
// don't change
|
||||||
|
#define XMF_RGBQUAD_TRANSPARENT XMF_COLOR_TRANSPARENT_B, \
|
||||||
|
XMF_COLOR_TRANSPARENT_G, \
|
||||||
|
XMF_COLOR_TRANSPARENT_R, \
|
||||||
|
0
|
||||||
|
// max. size. see Notes above
|
||||||
|
// alternatives
|
||||||
|
//#define XMF_MAXSIZE_CX (GetSystemMetrics(SM_CXSCREEN)-10)
|
||||||
|
//#define XMF_MAXSIZE_CY (GetSystemMetrics(SM_CYSCREEN)-50)
|
||||||
|
//#define XMF_MAXSIZE_CX (2*GetSystemMetrics(SM_CXSCREEN)/3)
|
||||||
|
//#define XMF_MAXSIZE_CY (2*GetSystemMetrics(SM_CYSCREEN)/3)
|
||||||
|
#define XMF_MAXSIZE_CX 4000
|
||||||
|
#define XMF_MAXSIZE_CY 4000
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
1900
Raw2Bmp_MFC/include/ximawnd.cpp
Normal file
1900
Raw2Bmp_MFC/include/ximawnd.cpp
Normal file
File diff suppressed because it is too large
Load Diff
125
Raw2Bmp_MFC/include/xiofile.h
Normal file
125
Raw2Bmp_MFC/include/xiofile.h
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#if !defined(__xiofile_h)
|
||||||
|
#define __xiofile_h
|
||||||
|
|
||||||
|
#include "xfile.h"
|
||||||
|
//#include <TCHAR.h>
|
||||||
|
|
||||||
|
class DLL_EXP CxIOFile : public CxFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxIOFile(FILE* fp = NULL)
|
||||||
|
{
|
||||||
|
m_fp = fp;
|
||||||
|
m_bCloseFile = (bool)(fp==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
~CxIOFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool Open(const TCHAR * filename, const TCHAR * mode)
|
||||||
|
{
|
||||||
|
if (m_fp) return false; // Can't re-open without closing first
|
||||||
|
|
||||||
|
m_fp = _tfopen(filename, mode);
|
||||||
|
if (!m_fp) return false;
|
||||||
|
|
||||||
|
m_bCloseFile = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual bool Close()
|
||||||
|
{
|
||||||
|
int32_t iErr = 0;
|
||||||
|
if ( (m_fp) && (m_bCloseFile) ){
|
||||||
|
iErr = fclose(m_fp);
|
||||||
|
m_fp = NULL;
|
||||||
|
}
|
||||||
|
return (bool)(iErr==0);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual size_t Read(void *buffer, size_t size, size_t count)
|
||||||
|
{
|
||||||
|
if (!m_fp) return 0;
|
||||||
|
return fread(buffer, size, count, m_fp);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual size_t Write(const void *buffer, size_t size, size_t count)
|
||||||
|
{
|
||||||
|
if (!m_fp) return 0;
|
||||||
|
return fwrite(buffer, size, count, m_fp);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual bool Seek(int32_t offset, int32_t origin)
|
||||||
|
{
|
||||||
|
if (!m_fp) return false;
|
||||||
|
return (bool)(fseek(m_fp, offset, origin) == 0);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual int32_t Tell()
|
||||||
|
{
|
||||||
|
if (!m_fp) return 0;
|
||||||
|
return ftell(m_fp);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual int32_t Size()
|
||||||
|
{
|
||||||
|
if (!m_fp) return -1;
|
||||||
|
int32_t pos,size;
|
||||||
|
pos = ftell(m_fp);
|
||||||
|
fseek(m_fp, 0, SEEK_END);
|
||||||
|
size = ftell(m_fp);
|
||||||
|
fseek(m_fp, pos,SEEK_SET);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual bool Flush()
|
||||||
|
{
|
||||||
|
if (!m_fp) return false;
|
||||||
|
return (bool)(fflush(m_fp) == 0);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual bool Eof()
|
||||||
|
{
|
||||||
|
if (!m_fp) return true;
|
||||||
|
return (bool)(feof(m_fp) != 0);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual int32_t Error()
|
||||||
|
{
|
||||||
|
if (!m_fp) return -1;
|
||||||
|
return ferror(m_fp);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual bool PutC(uint8_t c)
|
||||||
|
{
|
||||||
|
if (!m_fp) return false;
|
||||||
|
return (bool)(fputc(c, m_fp) == c);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual int32_t GetC()
|
||||||
|
{
|
||||||
|
if (!m_fp) return EOF;
|
||||||
|
return getc(m_fp);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual char * GetS(char *string, int32_t n)
|
||||||
|
{
|
||||||
|
if (!m_fp) return NULL;
|
||||||
|
return fgets(string,n,m_fp);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
virtual int32_t Scanf(const char *format, void* output)
|
||||||
|
{
|
||||||
|
if (!m_fp) return EOF;
|
||||||
|
return fscanf(m_fp, format, output);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
protected:
|
||||||
|
FILE *m_fp;
|
||||||
|
bool m_bCloseFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
213
Raw2Bmp_MFC/include/xmemfile.cpp
Normal file
213
Raw2Bmp_MFC/include/xmemfile.cpp
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
#include "xmemfile.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
CxMemFile::CxMemFile(uint8_t* pBuffer, uint32_t size)
|
||||||
|
{
|
||||||
|
m_pBuffer = pBuffer;
|
||||||
|
m_Position = 0;
|
||||||
|
m_Size = m_Edge = size;
|
||||||
|
m_bFreeOnClose = (bool)(pBuffer==0);
|
||||||
|
m_bEOF = false;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
CxMemFile::~CxMemFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::Close()
|
||||||
|
{
|
||||||
|
if ( (m_pBuffer) && (m_bFreeOnClose) ){
|
||||||
|
free(m_pBuffer);
|
||||||
|
m_pBuffer = NULL;
|
||||||
|
m_Size = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::Open()
|
||||||
|
{
|
||||||
|
if (m_pBuffer) return false; // Can't re-open without closing first
|
||||||
|
|
||||||
|
m_Position = m_Size = m_Edge = 0;
|
||||||
|
m_pBuffer=(uint8_t*)malloc(1);
|
||||||
|
m_bFreeOnClose = true;
|
||||||
|
|
||||||
|
return (m_pBuffer!=0);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
uint8_t* CxMemFile::GetBuffer(bool bDetachBuffer)
|
||||||
|
{
|
||||||
|
//can only detach, avoid inadvertantly attaching to
|
||||||
|
// memory that may not be ours [Jason De Arte]
|
||||||
|
if( bDetachBuffer )
|
||||||
|
m_bFreeOnClose = false;
|
||||||
|
return m_pBuffer;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
|
||||||
|
{
|
||||||
|
if (buffer==NULL) return 0;
|
||||||
|
|
||||||
|
if (m_pBuffer==NULL) return 0;
|
||||||
|
if (m_Position >= (int32_t)m_Size){
|
||||||
|
m_bEOF = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t nCount = (int32_t)(count*size);
|
||||||
|
if (nCount == 0) return 0;
|
||||||
|
|
||||||
|
int32_t nRead;
|
||||||
|
if (m_Position + nCount > (int32_t)m_Size){
|
||||||
|
m_bEOF = true;
|
||||||
|
nRead = (m_Size - m_Position);
|
||||||
|
} else
|
||||||
|
nRead = nCount;
|
||||||
|
|
||||||
|
memcpy(buffer, m_pBuffer + m_Position, nRead);
|
||||||
|
m_Position += nRead;
|
||||||
|
|
||||||
|
return (size_t)(nRead/size);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
size_t CxMemFile::Write(const void *buffer, size_t size, size_t count)
|
||||||
|
{
|
||||||
|
m_bEOF = false;
|
||||||
|
if (m_pBuffer==NULL) return 0;
|
||||||
|
if (buffer==NULL) return 0;
|
||||||
|
|
||||||
|
int32_t nCount = (int32_t)(count*size);
|
||||||
|
if (nCount == 0) return 0;
|
||||||
|
|
||||||
|
if (m_Position + nCount > m_Edge){
|
||||||
|
if (!Alloc(m_Position + nCount)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(m_pBuffer + m_Position, buffer, nCount);
|
||||||
|
|
||||||
|
m_Position += nCount;
|
||||||
|
|
||||||
|
if (m_Position > (int32_t)m_Size) m_Size = m_Position;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::Seek(int32_t offset, int32_t origin)
|
||||||
|
{
|
||||||
|
m_bEOF = false;
|
||||||
|
if (m_pBuffer==NULL) return false;
|
||||||
|
int32_t lNewPos = m_Position;
|
||||||
|
|
||||||
|
if (origin == SEEK_SET) lNewPos = offset;
|
||||||
|
else if (origin == SEEK_CUR) lNewPos += offset;
|
||||||
|
else if (origin == SEEK_END) lNewPos = m_Size + offset;
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
if (lNewPos < 0) lNewPos = 0;
|
||||||
|
|
||||||
|
m_Position = lNewPos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
int32_t CxMemFile::Tell()
|
||||||
|
{
|
||||||
|
if (m_pBuffer==NULL) return -1;
|
||||||
|
return m_Position;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
int32_t CxMemFile::Size()
|
||||||
|
{
|
||||||
|
if (m_pBuffer==NULL) return -1;
|
||||||
|
return m_Size;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::Flush()
|
||||||
|
{
|
||||||
|
if (m_pBuffer==NULL) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::Eof()
|
||||||
|
{
|
||||||
|
if (m_pBuffer==NULL) return true;
|
||||||
|
return m_bEOF;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
int32_t CxMemFile::Error()
|
||||||
|
{
|
||||||
|
if (m_pBuffer==NULL) return -1;
|
||||||
|
return (m_Position > (int32_t)m_Size);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::PutC(uint8_t c)
|
||||||
|
{
|
||||||
|
m_bEOF = false;
|
||||||
|
if (m_pBuffer==NULL) return false;
|
||||||
|
|
||||||
|
if (m_Position >= m_Edge){
|
||||||
|
if (!Alloc(m_Position + 1)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pBuffer[m_Position++] = c;
|
||||||
|
|
||||||
|
if (m_Position > (int32_t)m_Size) m_Size = m_Position;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
int32_t CxMemFile::GetC()
|
||||||
|
{
|
||||||
|
if (m_pBuffer==NULL || m_Position >= (int32_t)m_Size){
|
||||||
|
m_bEOF = true;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
return *(uint8_t*)((uint8_t*)m_pBuffer + m_Position++);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
char * CxMemFile::GetS(char *string, int32_t n)
|
||||||
|
{
|
||||||
|
n--;
|
||||||
|
int32_t c,i=0;
|
||||||
|
while (i<n){
|
||||||
|
c = GetC();
|
||||||
|
if (c == EOF) return 0;
|
||||||
|
string[i++] = (char)c;
|
||||||
|
if (c == '\n') break;
|
||||||
|
}
|
||||||
|
string[i] = 0;
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
int32_t CxMemFile::Scanf(const char *format, void* output)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
bool CxMemFile::Alloc(uint32_t dwNewLen)
|
||||||
|
{
|
||||||
|
if (dwNewLen > (uint32_t)m_Edge)
|
||||||
|
{
|
||||||
|
// find new buffer size
|
||||||
|
uint32_t dwNewBufferSize = (uint32_t)(((dwNewLen>>16)+1)<<16);
|
||||||
|
|
||||||
|
// allocate new buffer
|
||||||
|
if (m_pBuffer == NULL) m_pBuffer = (uint8_t*)malloc(dwNewBufferSize);
|
||||||
|
else m_pBuffer = (uint8_t*)realloc(m_pBuffer, dwNewBufferSize);
|
||||||
|
// I own this buffer now (caller knows nothing about it)
|
||||||
|
m_bFreeOnClose = true;
|
||||||
|
|
||||||
|
m_Edge = dwNewBufferSize;
|
||||||
|
}
|
||||||
|
return (m_pBuffer!=0);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
void CxMemFile::Free()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
42
Raw2Bmp_MFC/include/xmemfile.h
Normal file
42
Raw2Bmp_MFC/include/xmemfile.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#if !defined(__xmemfile_h)
|
||||||
|
#define __xmemfile_h
|
||||||
|
|
||||||
|
#include "xfile.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
class DLL_EXP CxMemFile : public CxFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CxMemFile(uint8_t* pBuffer = NULL, uint32_t size = 0);
|
||||||
|
~CxMemFile();
|
||||||
|
|
||||||
|
bool Open();
|
||||||
|
uint8_t* GetBuffer(bool bDetachBuffer = true);
|
||||||
|
|
||||||
|
virtual bool Close();
|
||||||
|
virtual size_t Read(void *buffer, size_t size, size_t count);
|
||||||
|
virtual size_t Write(const void *buffer, size_t size, size_t count);
|
||||||
|
virtual bool Seek(int32_t offset, int32_t origin);
|
||||||
|
virtual int32_t Tell();
|
||||||
|
virtual int32_t Size();
|
||||||
|
virtual bool Flush();
|
||||||
|
virtual bool Eof();
|
||||||
|
virtual int32_t Error();
|
||||||
|
virtual bool PutC(uint8_t c);
|
||||||
|
virtual int32_t GetC();
|
||||||
|
virtual char * GetS(char *string, int32_t n);
|
||||||
|
virtual int32_t Scanf(const char *format, void* output);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool Alloc(uint32_t nBytes);
|
||||||
|
void Free();
|
||||||
|
|
||||||
|
uint8_t* m_pBuffer;
|
||||||
|
uint32_t m_Size;
|
||||||
|
bool m_bFreeOnClose;
|
||||||
|
int32_t m_Position; //current position
|
||||||
|
int32_t m_Edge; //buffer size
|
||||||
|
bool m_bEOF;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
BIN
Raw2Bmp_MFC/include/zlib.lib
Normal file
BIN
Raw2Bmp_MFC/include/zlib.lib
Normal file
Binary file not shown.
BIN
Raw2Bmp_MFC/out.bmp
Normal file
BIN
Raw2Bmp_MFC/out.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.0 MiB |
BIN
Raw2Bmp_MFC/res/Raw2Bmp_MFC.ico
Normal file
BIN
Raw2Bmp_MFC/res/Raw2Bmp_MFC.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
Raw2Bmp_MFC/res/Raw2Bmp_MFC.rc2
Normal file
BIN
Raw2Bmp_MFC/res/Raw2Bmp_MFC.rc2
Normal file
Binary file not shown.
8
Raw2Bmp_MFC/stdafx.cpp
Normal file
8
Raw2Bmp_MFC/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
// stdafx.cpp : ǥ<><C7A5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>ҽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
// Raw2Bmp_MFC.pch<63><68> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˴ϴ<CBB4>.
|
||||||
|
// stdafx.obj<62><6A><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ե˴ϴ<CBB4>.
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
|
||||||
71
Raw2Bmp_MFC/stdafx.h
Normal file
71
Raw2Bmp_MFC/stdafx.h
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
// stdafx.h : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD>
|
||||||
|
// ǥ<><C7A5> <20>ý<EFBFBD><C3BD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// <20><><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _SECURE_ATL
|
||||||
|
#define _SECURE_ATL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef VC_EXTRALEAN
|
||||||
|
#define VC_EXTRALEAN // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Windows <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "targetver.h"
|
||||||
|
|
||||||
|
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // <20>Ϻ<EFBFBD> CString <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>˴ϴ<CBB4>.
|
||||||
|
|
||||||
|
// MFC<46><43> <20><><EFBFBD><EFBFBD> <20>κа<CEBA> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>⸦ <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
#define _AFX_ALL_WARNINGS
|
||||||
|
|
||||||
|
#include <afxwin.h> // MFC <20>ٽ<EFBFBD> <20><> ǥ<><C7A5> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
#include <afxext.h> // MFC Ȯ<><C8AE><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
|
||||||
|
#include <afxdisp.h> // MFC <20>ڵ<EFBFBD>ȭ Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _AFX_NO_OLE_SUPPORT
|
||||||
|
#include <afxdtctl.h> // Internet Explorer 4 <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD>ѿ<EFBFBD> <20><><EFBFBD><EFBFBD> MFC <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
#endif
|
||||||
|
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||||
|
#include <afxcmn.h> // Windows <20><><EFBFBD><EFBFBD> <20><>Ʈ<EFBFBD>ѿ<EFBFBD> <20><><EFBFBD><EFBFBD> MFC <20><><EFBFBD><EFBFBD><EFBFBD>Դϴ<D4B4>.
|
||||||
|
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||||
|
|
||||||
|
#include <afxcontrolbars.h> // MFC<46><43> <20><><EFBFBD><EFBFBD> <20><> <20><>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
|
||||||
|
#include <afxsock.h> // MFC <20><><EFBFBD><EFBFBD> Ȯ<><C8AE>
|
||||||
|
|
||||||
|
|
||||||
|
#pragma comment (lib, "cximage.lib")
|
||||||
|
#pragma comment (lib, "Jpeg.lib")
|
||||||
|
#pragma comment (lib, "png.lib")
|
||||||
|
#pragma comment (lib, "mng.lib")
|
||||||
|
#pragma comment (lib, "Tiff.lib")
|
||||||
|
#pragma comment (lib, "zlib.lib")
|
||||||
|
#pragma comment (lib, "jasper.lib")
|
||||||
|
#pragma comment (lib, "libdcr.lib")
|
||||||
|
#pragma comment (lib, "libpsd.lib")
|
||||||
|
#pragma comment (lib, "jbig.lib")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _UNICODE
|
||||||
|
#if defined _M_IX86
|
||||||
|
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||||
|
#elif defined _M_X64
|
||||||
|
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||||
|
#else
|
||||||
|
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
8
Raw2Bmp_MFC/targetver.h
Normal file
8
Raw2Bmp_MFC/targetver.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> SDKDDKVer.h<><68> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Windows <20>÷<EFBFBD><C3B7><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD> Windows <20>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> SDKDDKVer.h<><68> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||||
|
// WinSDKVer.h<><68> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> _WIN32_WINNT <20><>ũ<EFBFBD>θ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻʽÿ<CABD>.
|
||||||
|
|
||||||
|
#include <SDKDDKVer.h>
|
||||||
Reference in New Issue
Block a user