Move dependencies into new dependencies folder for cleanliness

Remove blargg audio core but leave interpolation
This commit is contained in:
DJRobX 2007-11-09 01:40:27 +00:00
parent e2afbd964c
commit fc82c5b342
67 changed files with 1047 additions and 28870 deletions

20
VBA.sln
View File

@ -2,10 +2,16 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisualBoyAdvance", "VBA.vcproj", "{6D4C5EC8-933F-4C05-A1BF-498E658576DF}"
ProjectSection(ProjectDependencies) = postProject
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092} = {B938FBD9-C7F9-4BF7-8C27-68865D1FA092}
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE} = {DB5C12E9-BCD3-4517-8708-475C0D1D88CE}
{96E945F7-0377-48DA-A5F8-1C192DE9F25F} = {96E945F7-0377-48DA-A5F8-1C192DE9F25F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cximage", "src\win32\dependencies\cximage\cximage.vcproj", "{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\dependencies\zlib\zlib.vcproj", "{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\dependencies\libpng\libpng.vcproj", "{96E945F7-0377-48DA-A5F8-1C192DE9F25F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cximage", "..\dependencies\cximage\cximage.vcproj", "{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -20,6 +26,18 @@ Global
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Optimized|Win32.Build.0 = Optimized|Win32
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.ActiveCfg = Release|Win32
{6D4C5EC8-933F-4C05-A1BF-498E658576DF}.Release|Win32.Build.0 = Release|Win32
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|Win32.ActiveCfg = Debug|Win32
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Debug|Win32.Build.0 = Debug|Win32
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Optimized|Win32.ActiveCfg = Release|Win32
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Optimized|Win32.Build.0 = Release|Win32
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|Win32.ActiveCfg = Release|Win32
{B938FBD9-C7F9-4BF7-8C27-68865D1FA092}.Release|Win32.Build.0 = Release|Win32
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|Win32.ActiveCfg = Debug|Win32
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Debug|Win32.Build.0 = Debug|Win32
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Optimized|Win32.ActiveCfg = Release|Win32
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Optimized|Win32.Build.0 = Release|Win32
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|Win32.ActiveCfg = Release|Win32
{96E945F7-0377-48DA-A5F8-1C192DE9F25F}.Release|Win32.Build.0 = Release|Win32
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|Win32.ActiveCfg = Debug|Win32
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Debug|Win32.Build.0 = Debug|Win32
{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}.Optimized|Win32.ActiveCfg = Release|Win32

View File

@ -191,7 +191,7 @@
Name="VCLinkerTool"
RegisterOutput="false"
IgnoreImportLibrary="false"
AdditionalDependencies="nafxcw.lib LIBCMT.lib Vfw32.Lib OpenGL32.Lib dinput8.lib winmm.lib dxguid.lib ddraw.lib d3d9.lib d3dx9.lib Dsound.lib zlib.lib libpng.lib"
AdditionalDependencies="nafxcw.lib LIBCMT.lib Vfw32.Lib OpenGL32.Lib dinput8.lib winmm.lib dxguid.lib ddraw.lib d3d9.lib d3dx9.lib Dsound.lib"
ShowProgress="0"
OutputFile="$(ProjectDir)VisualBoyAdvance.exe"
Version=""
@ -1118,26 +1118,6 @@
>
</File>
</Filter>
<Filter
Name="Blargg"
>
<File
RelativePath=".\src\Gb_Apu\Blip_Buffer.cpp"
>
</File>
<File
RelativePath=".\src\Gb_Apu\Gb_Apu.cpp"
>
</File>
<File
RelativePath=".\src\Gb_Apu\Gb_Oscs.cpp"
>
</File>
<File
RelativePath=".\src\Gb_Apu\Multi_Buffer.cpp"
>
</File>
</Filter>
<Filter
Name="Linking"
>

View File

@ -23,7 +23,6 @@
#include "System.h"
#include "Port.h"
#include "RTC.h"
#include "Sound.h"
extern bool cpuSramEnabled;
extern bool cpuFlashEnabled;
@ -98,9 +97,9 @@ static inline u32 CPUReadMemory(u32 address)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2])
value = soundRead32(address & 0x3fC);
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
else
value = soundRead16(address & 0x3fc);
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
} else goto unreadable;
break;
case 5:
@ -223,7 +222,7 @@ if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fe])
{
value = soundRead16(address & 0x3fe);
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
{
if (((address & 0x3fe) == 0x100) && timer0On)
@ -337,7 +336,7 @@ static inline u8 CPUReadByte(u32 address)
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3ff])
return soundRead(address & 0x3ff);
return ioMem[address & 0x3ff];
else goto unreadable;
case 5:
return paletteRAM[address & 0x3ff];

View File

@ -320,7 +320,7 @@ void Blip_Synth_::volume_unit( double new_unit )
factor *= 2.0;
}
// if ( shift )
if ( shift )
{
kernel_unit >>= shift;
assert( kernel_unit > 0 ); // fails if volume unit is too low

View File

@ -198,7 +198,7 @@ void Gb_Noise::run( gb_time_t time, gb_time_t end_time, int playing )
const blip_resampled_time_t resampled_period =
output->resampled_duration( period );
blip_resampled_time_t resampled_time = output->resampled_time( time );
// unsigned bits = this->bits;
unsigned bits = this->bits;
int delta = amp * 2;
do
@ -216,7 +216,7 @@ void Gb_Noise::run( gb_time_t time, gb_time_t end_time, int playing )
}
while ( time < end_time );
//this->bits = bits;
this->bits = bits;
last_amp = delta >> 1;
}
delay = time - end_time;

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@
#ifndef VBA_SOUND_H
#define VBA_SOUND_H
#include "System.h"
#define NR10 0x60
#define NR11 0x62
#define NR12 0x63
@ -51,7 +53,7 @@
extern void setSoundFn();
extern void (*psoundTickfn)();
extern void soundShutdown();
extern bool soundInit(bool gba=true);
extern bool soundInit();
extern void soundPause();
extern void soundResume();
extern void soundEnable(int);
@ -67,13 +69,9 @@ extern void soundSetQuality(int);
extern void setsystemSoundOn(bool value);
extern void setsoundPaused(bool value);
extern void setsoundMasterOn(bool value);
extern void interp_rate();
//extern int SOUND_TICKS;
extern int SOUND_CLOCK_TICKS;
extern u8 soundRead(u32);
extern u16 soundRead16(u32);
extern u32 soundRead32(u32);
extern int soundTicks;
extern bool soundOffFlag;
extern bool soundPaused;
@ -89,14 +87,4 @@ extern bool soundEcho;
extern bool soundLowPass;
extern bool soundReverse;
#include "Gb_Apu/Multi_Buffer.h"
#include "Gb_Apu/Gb_Apu.h"
extern Multi_Buffer * apu_out;
extern Gb_Apu * apu;
extern const BOOST::uint8_t sound_data [Gb_Apu::register_count];
extern void interp_rate();
#endif // VBA_SOUND_H

View File

@ -998,7 +998,7 @@ void gbWriteMemory(register u16 address, register u8 value)
case 0x3d:
case 0x3e:
case 0x3f: {
SOUND_EVENT(address,value);
gbMemory[address] = value;
return;
}
@ -1783,11 +1783,6 @@ u8 gbReadMemory(register u16 address)
}
if(address >= 0xff00) {
if (address >= 0xFF10 && address <= 0xFF3F) {
return gbSoundRead(address);
}
switch(address & 0x00ff) {
case 0x00:
{
@ -3532,8 +3527,6 @@ static bool gbWriteSaveState(gzFile gzFile)
utilGzWrite(gzFile, &gbDataMMM01, sizeof(gbDataMMM01));
utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
for (int i = 0xFF10; i <= 0xFF3F; i++) gbMemory[i] = gbReadMemory(i);
utilGzWrite(gzFile, &gbMemory[0x8000], 0x8000);
@ -3725,8 +3718,6 @@ static bool gbReadSaveState(gzFile gzFile)
utilGzRead(gzFile, &gbMemory[0x8000], 0x8000);
for (int i = 0xFF10; i <= 0xFF3F; i++) gbSoundEvent(i, gbMemory[i]);
if(gbRamSize && gbRam) {
if (version < 11)
utilGzRead(gzFile, gbRam, gbRamSize);

View File

@ -23,9 +23,6 @@
#include "gbGlobals.h"
#include "gbSound.h"
#include "../Gb_Apu/Multi_Buffer.h"
#include "../Gb_Apu/Gb_Apu.h"
extern u8 soundBuffer[6][735];
extern u16 soundFinalWave[1470];
extern int soundVolume;
@ -59,9 +56,6 @@ extern int soundBufferIndex;
int soundVIN = 0;
extern int soundDebug;
extern Multi_Buffer * apu_out;
extern Gb_Apu * apu;
extern int sound1On;
extern int sound1ATL;
int sound1ATLreload;
@ -138,45 +132,7 @@ extern bool soundLowPass;
extern bool soundReverse;
extern bool soundOffFlag;
u8 gbSoundRead(u16 address)
{
if (address < NR10 || address > 0xFF3F || !apu) return gbMemory[address];
if (address == NR51) return soundBalance;
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1));
int ret = apu->read_register(clock, address);
switch ( address )
{
case NR10:
ret |= 0x80; break;
case NR11:
case NR21:
ret |= 0x3F; break;
case NR13:
case NR23:
case NR31:
case NR33:
ret = 0xFF; break;
case NR14:
case NR24:
case NR34:
case NR44:
ret |= 0xBF; break;
case NR30:
ret |= 0x7F; break;
case NR32:
ret |= 0x9F; break;
}
return ret;
}
bool gbDigitalSound = false;
void gbSoundEvent(register u16 address, register int data)
{
@ -190,58 +146,481 @@ void gbSoundEvent(register u16 address, register int data)
log("Sound event: %08lx %02x\n", address, data);
}
#endif
if (apu && address >= NR10 && address <= 0xFF3F)
{
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1));
if (address == NR50)
{
apu->write_register(clock, address, data);
switch(address) {
case NR10:
gbMemory[address] = data | 0x80;
sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
sound1SweepSteps = data & 7;
sound1SweepUpDown = data & 0x08;
sound1SweepStep = 0;
break;
case NR11:
gbMemory[address] = data | 0x3f;
sound1Wave = soundWavePattern[data >> 6];
sound1ATL = sound1ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR12:
sound1EnvelopeVolume = data >> 4;
sound1EnvelopeUpDown = data & 0x08;
sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);
break;
case NR13:
gbMemory[address] = 0xff;
freq1low = data;
freq = ((((int)(freq1high & 7)) << 8) | freq1low);
sound1ATL = sound1ATLreload;
freq = 2048 - freq;
if(freq) {
sound1Skip = SOUND_MAGIC / freq;
} else
sound1Skip = 0;
break;
case NR14:
gbMemory[address] = data | 0xbf;
freq1high = data;
freq = ((((int)(freq1high & 7)) << 8) | freq1low);
freq = 2048 - freq;
sound1ATL = sound1ATLreload;
sound1Continue = data & 0x40;
if(freq) {
sound1Skip = SOUND_MAGIC / freq;
} else
sound1Skip = 0;
if(data & 0x80) {
gbMemory[NR52] |= 1;
sound1EnvelopeVolume = gbMemory[NR12] >> 4;
sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;
sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);
sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);
sound1SweepSteps = gbMemory[NR10] & 7;
sound1SweepUpDown = gbMemory[NR10] & 0x08;
sound1SweepStep = 0;
sound1Index = 0;
sound1On = 1;
}
else if (address == NR51)
{
soundBalance = data;
apu->write_register(clock, address, data & soundEnableFlag);
break;
case NR21:
gbMemory[address] = data | 0x3f;
sound2Wave = soundWavePattern[data >> 6];
sound2ATL = sound2ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR22:
sound2EnvelopeVolume = data >> 4;
sound2EnvelopeUpDown = data & 0x08;
sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);
break;
case NR23:
gbMemory[address] = 0xff;
freq2low = data;
freq = (((int)(freq2high & 7)) << 8) | freq2low;
sound2ATL = sound2ATLreload;
freq = 2048 - freq;
if(freq) {
sound2Skip = SOUND_MAGIC / freq;
} else
sound2Skip = 0;
break;
case NR24:
gbMemory[address] = data | 0xbf;
freq2high = data;
freq = (((int)(freq2high & 7)) << 8) | freq2low;
freq = 2048 - freq;
sound2ATL = sound2ATLreload;
sound2Continue = data & 0x40;
if(freq) {
sound2Skip = SOUND_MAGIC / freq;
} else
sound2Skip = 0;
if(data & 0x80) {
gbMemory[NR52] |= 2;
sound2EnvelopeVolume = gbMemory[NR22] >> 4;
sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;
sound2ATL = sound2ATLreload;
sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);
sound2Index = 0;
sound2On = 1;
}
else
apu->write_register(clock, address, data);
break;
case NR30:
gbMemory[address] = data | 0x7f;
if(!(data & 0x80)) {
gbMemory[NR52] &= 0xfb;
sound3On = 0;
}
break;
case NR31:
gbMemory[address] = 0xff;
sound3ATL = sound3ATLreload = 172 * (256-data);
break;
case NR32:
gbMemory[address] = data | 0x9f;
sound3OutputLevel = (data >> 5) & 3;
break;
case NR33:
gbMemory[address] = 0xff;
freq3low = data;
freq = 2048 - (((int)(freq3high&7) << 8) | freq3low);
if(freq) {
sound3Skip = SOUND_MAGIC_2 / freq;
} else
sound3Skip = 0;
break;
case NR34:
gbMemory[address] = data | 0xbf;
freq3high = data;
freq = 2048 - (((int)(freq3high&7) << 8) | freq3low);
if(freq) {
sound3Skip = SOUND_MAGIC_2 / freq;
} else {
sound3Skip = 0;
}
sound3Continue = data & 0x40;
if((data & 0x80) && (gbMemory[NR30] & 0x80)) {
gbMemory[NR52] |= 4;
sound3ATL = sound3ATLreload;
sound3Index = 0;
sound3On = 1;
}
break;
case NR41:
sound4ATL = sound4ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR42:
sound4EnvelopeVolume = data >> 4;
sound4EnvelopeUpDown = data & 0x08;
sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);
break;
case NR43:
freq = freq4 = soundFreqRatio[data & 7];
sound4NSteps = data & 0x08;
sound4Skip = (freq << 8) / NOISE_MAGIC;
sound4Clock = data >> 4;
freq = freq / soundShiftClock[sound4Clock];
sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
break;
case NR44:
gbMemory[address] = data | 0xbf;
sound4Continue = data & 0x40;
if(data & 0x80) {
gbMemory[NR52] |= 8;
sound4EnvelopeVolume = gbMemory[NR42] >> 4;
sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;
sound4ATL = sound4ATLreload;
sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);
sound4On = 1;
sound4Index = 0;
sound4ShiftIndex = 0;
if(sound4NSteps)
sound4ShiftRight = 0x7fff;
else
sound4ShiftRight = 0x7f;
}
break;
case NR50:
soundVIN = data & 0x88;
soundLevel1 = data & 7;
soundLevel2 = (data >> 4) & 7;
break;
case NR51:
soundBalance = (data & soundEnableFlag);
break;
case NR52:
soundMasterOn = data & 0x80;
if(!(data & 0x80)) {
sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;
gbMemory[address] &= 0xf0;
}
gbMemory[address] = data & 0x80 | 0x70 | (gbMemory[address] & 0xf);
break;
}
gbDigitalSound = true;
if(sound1On && sound1EnvelopeVolume != 0)
gbDigitalSound = false;
if(sound2On && sound2EnvelopeVolume != 0)
gbDigitalSound = false;
if(sound3On && sound3OutputLevel != 0)
gbDigitalSound = false;
if(sound4On && sound4EnvelopeVolume != 0)
gbDigitalSound = false;
}
void gbSoundChannel1()
{
int vol = sound1EnvelopeVolume;
int freq = 0;
int value = 0;
if(sound1On && (sound1ATL || !sound1Continue)) {
sound1Index += soundQuality*sound1Skip;
sound1Index &= 0x1fffffff;
value = ((s8)sound1Wave[sound1Index>>24]) * vol;
}
soundBuffer[0][soundIndex] = value;
if(sound1On) {
if(sound1ATL) {
sound1ATL-=soundQuality;
if(sound1ATL <=0 && sound1Continue) {
gbMemory[NR52] &= 0xfe;
sound1On = 0;
}
}
if(sound1EnvelopeATL) {
sound1EnvelopeATL-=soundQuality;
if(sound1EnvelopeATL<=0) {
if(sound1EnvelopeUpDown) {
if(sound1EnvelopeVolume < 15)
sound1EnvelopeVolume++;
} else {
if(sound1EnvelopeVolume)
sound1EnvelopeVolume--;
}
sound1EnvelopeATL += sound1EnvelopeATLReload;
}
}
if(sound1SweepATL) {
sound1SweepATL-=soundQuality;
if(sound1SweepATL<=0) {
freq = (((int)(freq1high & 7)) << 8) | freq1low;
int updown = 1;
if(sound1SweepUpDown)
updown = -1;
int newfreq = 0;
if(sound1SweepSteps) {
newfreq = freq + updown * freq / (1 << sound1SweepSteps);
if(newfreq == freq)
newfreq = 0;
} else
newfreq = freq;
if(newfreq < 0) {
sound1SweepATL += sound1SweepATLReload;
} else if(newfreq > 2047) {
sound1SweepATL = 0;
sound1On = 0;
gbMemory[NR52] &= 0xfe;
} else {
sound1SweepATL += sound1SweepATLReload;
sound1Skip = SOUND_MAGIC/(2048 - newfreq);
freq1low = newfreq & 0xff;
freq1high = (freq1high & 0xf8) |((newfreq >> 8) & 7);
}
}
}
}
}
void gbSoundChannel2()
{
// int freq = 0;
int vol = sound2EnvelopeVolume;
int value = 0;
if(sound2On && (sound2ATL || !sound2Continue)) {
sound2Index += soundQuality*sound2Skip;
sound2Index &= 0x1fffffff;
value = ((s8)sound2Wave[sound2Index>>24]) * vol;
}
soundBuffer[1][soundIndex] = value;
if(sound2On) {
if(sound2ATL) {
sound2ATL-=soundQuality;
if(sound2ATL <= 0 && sound2Continue) {
gbMemory[NR52] &= 0xfd;
sound2On = 0;
}
}
if(sound2EnvelopeATL) {
sound2EnvelopeATL-=soundQuality;
if(sound2EnvelopeATL <= 0) {
if(sound2EnvelopeUpDown) {
if(sound2EnvelopeVolume < 15)
sound2EnvelopeVolume++;
} else {
if(sound2EnvelopeVolume)
sound2EnvelopeVolume--;
}
sound2EnvelopeATL += sound2EnvelopeATLReload;
}
}
}
}
void gbSoundChannel3()
{
int value = 0;
if(sound3On && (sound3ATL || !sound3Continue)) {
value = sound3Last;
sound3Index += soundQuality*sound3Skip;
sound3Index &= 0x1fffffff;
value = gbMemory[0xff30 + (sound3Index>>25)];
if( (sound3Index & 0x01000000)) {
value &= 0x0f;
} else {
value >>= 4;
}
value -= 8;
switch(sound3OutputLevel) {
case 0:
value = 0;
break;
case 1:
break;
case 2:
value = (value >> 1);
break;
case 3:
value = (value >> 2);
break;
}
sound3Last = value;
}
soundBuffer[2][soundIndex] = value;
if(sound3On) {
if(sound3ATL) {
sound3ATL-=soundQuality;
if(sound3ATL <= 0 && sound3Continue) {
gbMemory[NR52] &= 0xfb;
sound3On = 0;
}
}
}
}
void gbSoundChannel4()
{
int vol = sound4EnvelopeVolume;
int value = 0;
if(sound4Clock <= 0x0c) {
if(sound4On && (sound4ATL || !sound4Continue)) {
sound4Index += soundQuality*sound4Skip;
sound4ShiftIndex += soundQuality*sound4ShiftSkip;
if(sound4NSteps) {
while(sound4ShiftIndex > 0x1fffff) {
sound4ShiftRight = (((sound4ShiftRight << 6) ^
(sound4ShiftRight << 5)) & 0x40) |
(sound4ShiftRight >> 1);
sound4ShiftIndex -= 0x200000;
}
} else {
while(sound4ShiftIndex > 0x1fffff) {
sound4ShiftRight = (((sound4ShiftRight << 14) ^
(sound4ShiftRight << 13)) & 0x4000) |
(sound4ShiftRight >> 1);
sound4ShiftIndex -= 0x200000;
}
}
sound4Index &= 0x1fffff;
sound4ShiftIndex &= 0x1fffff;
value = ((sound4ShiftRight & 1)*2-1) * vol;
} else {
value = 0;
}
}
soundBuffer[3][soundIndex] = value;
if(sound4On) {
if(sound4ATL) {
sound4ATL-=soundQuality;
if(sound4ATL <= 0 && sound4Continue) {
gbMemory[NR52] &= 0xf7;
sound4On = 0;
}
}
if(sound4EnvelopeATL) {
sound4EnvelopeATL-=soundQuality;
if(sound4EnvelopeATL <= 0) {
if(sound4EnvelopeUpDown) {
if(sound4EnvelopeVolume < 15)
sound4EnvelopeVolume++;
} else {
if(sound4EnvelopeVolume)
sound4EnvelopeVolume--;
}
sound4EnvelopeATL += sound4EnvelopeATLReload;
}
}
}
}
void gbSoundMix()
{
int res = 0;
blip_sample_t out[2] = {0, 0};
if ( ! apu_out ) return;
while (!apu_out->read_samples(&out[0], 2))
{
int ticks = SOUND_CLOCK_TICKS * 95 / (24 * (gbSpeed ? 2 : 1));
bool was_stereo = apu->end_frame( ticks );
apu_out->end_frame( ticks, was_stereo );
if(soundBalance & 16) {
res += ((s8)soundBuffer[0][soundIndex]);
}
if(soundBalance & 32) {
res += ((s8)soundBuffer[1][soundIndex]);
}
if(soundBalance & 64) {
res += ((s8)soundBuffer[2][soundIndex]);
}
if(soundBalance & 128) {
res += ((s8)soundBuffer[3][soundIndex]);
}
res = out[0];
//res = (res * 7 * 60) >> 8;
if(gbDigitalSound)
res *= soundLevel1*256;
else
res *= soundLevel1*60;
if(soundEcho) {
res *= 2;
@ -285,7 +664,25 @@ void gbSoundMix()
else
soundFinalWave[soundBufferIndex++] = res;
res = out[1];
res = 0;
if(soundBalance & 1) {
res += ((s8)soundBuffer[0][soundIndex]);
}
if(soundBalance & 2) {
res += ((s8)soundBuffer[1][soundIndex]);
}
if(soundBalance & 4) {
res += ((s8)soundBuffer[2][soundIndex]);
}
if(soundBalance & 8) {
res += ((s8)soundBuffer[3][soundIndex]);
}
if(gbDigitalSound)
res *= soundLevel2*256;
else
res *= soundLevel2*60;
if(soundEcho) {
res *= 2;
@ -337,10 +734,10 @@ void gbSoundTick()
{
if(systemSoundOn) {
if(soundMasterOn) {
/*gbSoundChannel1();
gbSoundChannel1();
gbSoundChannel2();
gbSoundChannel3();
gbSoundChannel4();*/
gbSoundChannel4();
gbSoundMix();
} else {
@ -366,7 +763,7 @@ void gbSoundTick()
void gbSoundReset()
{
soundPaused = true;
soundPaused = 1;
soundPlay = 0;
SOUND_CLOCK_TICKS = soundQuality * 24;
soundTicks = SOUND_CLOCK_TICKS;
@ -378,7 +775,7 @@ void gbSoundReset()
soundLevel2 = 7;
soundVIN = 0;
/*sound1On = 0;
sound1On = 0;
sound1ATL = 0;
sound1Skip = 0;
sound1Index = 0;
@ -424,48 +821,53 @@ void gbSoundReset()
sound4EnvelopeVolume = 0;
sound4EnvelopeATL = 0;
sound4EnvelopeUpDown = 0;
sound4EnvelopeATLReload = 0;*/
sound4EnvelopeATLReload = 0;
// don't translate
if(soundDebug) {
log("*** Sound Init ***\n");
}
gbSoundEvent(0xff10, 0x80);
gbSoundEvent(0xff11, 0xbf);
gbSoundEvent(0xff12, 0xf3);
gbSoundEvent(0xff14, 0xbf);
gbSoundEvent(0xff16, 0x3f);
gbSoundEvent(0xff17, 0x00);
gbSoundEvent(0xff19, 0xbf);
if (apu_out)
{
apu_out->clear();
apu->reset(false);
gbSoundEvent(0xff1a, 0x7f);
gbSoundEvent(0xff1b, 0xff);
gbSoundEvent(0xff1c, 0xbf);
gbSoundEvent(0xff1e, 0xbf);
extern const BOOST::uint8_t sound_data[Gb_Apu::end_addr - Gb_Apu::start_addr + 1];
gbSoundEvent(0xff20, 0xff);
gbSoundEvent(0xff21, 0x00);
gbSoundEvent(0xff22, 0x00);
gbSoundEvent(0xff23, 0xbf);
gbSoundEvent(0xff24, 0x77);
gbSoundEvent(0xff25, 0xf3);
int addr = 0;
while (addr < 0x30) {
apu->write_register( 0, 0xFF10 + addr, sound_data [ addr ] );
addr++;
}
}
if (gbHardware & 0x4)
gbSoundEvent(0xff26, 0xf0);
else
gbSoundEvent(0xff26, 0xf1);
// don't translate
if(soundDebug) {
log("*** Sound Init Complete ***\n");
}
/*sound1On = 0;
sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;*/
sound4On = 0;
if (apu)
{
int addr = 0xff30;
int addr = 0xff30;
while(addr < 0xff40) {
/*gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;*/
gbSoundEvent(addr++, 0x00);
gbSoundEvent(addr++, 0xFF);
}
while(addr < 0xff40) {
gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;
}
memset(soundFinalWave, 0x00, soundBufferLen);
@ -475,7 +877,7 @@ void gbSoundReset()
soundEchoIndex = 0;
}
extern bool soundInit(bool gb);
extern bool soundInit();
extern void soundShutdown();
void gbSoundSetQuality(int quality)
@ -486,7 +888,7 @@ void gbSoundSetQuality(int quality)
soundQuality = quality;
soundNextPosition = 0;
if(!soundOffFlag)
soundInit(false);
soundInit();
SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * 24 * soundQuality;
soundIndex = 0;
soundBufferIndex = 0;

View File

@ -22,7 +22,6 @@
#define NR12 0xff12
#define NR13 0xff13
#define NR14 0xff14
#define NR20 0xff15
#define NR21 0xff16
#define NR22 0xff17
#define NR23 0xff18
@ -32,7 +31,6 @@
#define NR32 0xff1c
#define NR33 0xff1d
#define NR34 0xff1e
#define NR40 0xff1f
#define NR41 0xff20
#define NR42 0xff21
#define NR43 0xff22
@ -56,8 +54,6 @@ extern void gbSoundReadGame(int,gzFile);
extern void gbSoundEvent(register u16, register int);
extern void gbSoundSetQuality(int);
extern u8 gbSoundRead(u16 address);
extern int soundTicks;
extern int soundQuality;
extern int SOUND_CLOCK_TICKS;

View File

@ -620,7 +620,7 @@ bool MainWnd::FileRun()
soundReset();
} else {
if(!soundOffFlag)
soundInit(!(theApp.cartridgeType==1));
soundInit();
theApp.soundInitialized = true;
}

View File

@ -1,367 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="cximage"
ProjectGUID="{DB5C12E9-BCD3-4517-8708-475C0D1D88CE}"
RootNamespace="cximage"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;JAS_WIN_MSVC_BUILD"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;JAS_WIN_MSVC_BUILD"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\tif_xfile.cpp"
>
</File>
<File
RelativePath=".\ximabmp.cpp"
>
</File>
<File
RelativePath=".\ximadsp.cpp"
>
</File>
<File
RelativePath=".\ximaenc.cpp"
>
</File>
<File
RelativePath=".\ximaexif.cpp"
>
</File>
<File
RelativePath=".\ximage.cpp"
>
</File>
<File
RelativePath=".\ximagif.cpp"
>
</File>
<File
RelativePath=".\ximahist.cpp"
>
</File>
<File
RelativePath=".\ximaico.cpp"
>
</File>
<File
RelativePath=".\ximainfo.cpp"
>
</File>
<File
RelativePath=".\ximaint.cpp"
>
</File>
<File
RelativePath=".\ximaj2k.cpp"
>
</File>
<File
RelativePath=".\ximajas.cpp"
>
</File>
<File
RelativePath=".\ximajbg.cpp"
>
</File>
<File
RelativePath=".\ximajpg.cpp"
>
</File>
<File
RelativePath=".\ximalpha.cpp"
>
</File>
<File
RelativePath=".\ximalyr.cpp"
>
</File>
<File
RelativePath=".\ximamng.cpp"
>
</File>
<File
RelativePath=".\ximapal.cpp"
>
</File>
<File
RelativePath=".\ximapcx.cpp"
>
</File>
<File
RelativePath=".\ximapng.cpp"
>
</File>
<File
RelativePath=".\ximasel.cpp"
>
</File>
<File
RelativePath=".\ximatga.cpp"
>
</File>
<File
RelativePath=".\ximath.cpp"
>
</File>
<File
RelativePath=".\ximatif.cpp"
>
</File>
<File
RelativePath=".\ximatran.cpp"
>
</File>
<File
RelativePath=".\ximawbmp.cpp"
>
</File>
<File
RelativePath=".\ximawmf.cpp"
>
</File>
<File
RelativePath=".\ximawnd.cpp"
>
</File>
<File
RelativePath=".\xmemfile.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\xfile.h"
>
</File>
<File
RelativePath=".\ximabmp.h"
>
</File>
<File
RelativePath=".\ximacfg.h"
>
</File>
<File
RelativePath=".\ximadef.h"
>
</File>
<File
RelativePath=".\ximage.h"
>
</File>
<File
RelativePath=".\ximagif.h"
>
</File>
<File
RelativePath=".\ximaico.h"
>
</File>
<File
RelativePath=".\ximaiter.h"
>
</File>
<File
RelativePath=".\ximaj2k.h"
>
</File>
<File
RelativePath=".\ximajas.h"
>
</File>
<File
RelativePath=".\ximajbg.h"
>
</File>
<File
RelativePath=".\ximajpg.h"
>
</File>
<File
RelativePath=".\ximamng.h"
>
</File>
<File
RelativePath=".\ximapcx.h"
>
</File>
<File
RelativePath=".\ximapng.h"
>
</File>
<File
RelativePath=".\ximatga.h"
>
</File>
<File
RelativePath=".\ximath.h"
>
</File>
<File
RelativePath=".\ximatif.h"
>
</File>
<File
RelativePath=".\ximawbmp.h"
>
</File>
<File
RelativePath=".\ximawmf.h"
>
</File>
<File
RelativePath=".\xiofile.h"
>
</File>
<File
RelativePath=".\xmemfile.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,48 +0,0 @@
This copy of the CxImage notices is provided for your convenience. In case of
any discrepancy between this copy and the notices in the file ximage.h that is
included in the CxImage distribution, the latter shall prevail.
If you modify CxImage you may insert additional notices immediately following
this sentence.
--------------------------------------------------------------------------------
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
CxImage version 5.99c 17/Oct/2004
CxImage : Copyright (C) 2001 - 2004, 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
--------------------------------------------------------------------------------

View File

@ -1,208 +0,0 @@
/*
* 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 "xfile.h"
static tsize_t
_tiffReadProcEx(thandle_t fd, tdata_t buf, tsize_t size)
{
return ((CxFile*)fd)->Read(buf, 1, size);
}
static tsize_t
_tiffWriteProcEx(thandle_t fd, tdata_t buf, tsize_t size)
{
return ((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(int 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 = fd;
return (tif);
}
extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode)
{
return (_TIFFFdOpen((int)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));
}
static void
Win32WarningHandler(const char* module, const char* fmt, va_list ap)
{
#ifdef _DEBUG
#if (!defined(_CONSOLE) && defined(WIN32))
LPTSTR szTitle;
LPTSTR szTmp;
LPCTSTR szTitleText = "%s Warning";
LPCTSTR szDefaultModule = "TIFFLIB";
szTmp = (module == NULL) ? (LPTSTR)szDefaultModule : (LPTSTR)module;
if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (lstrlen(szTmp) +
lstrlen(szTitleText) + lstrlen(fmt) + 128)*sizeof(TCHAR))) == NULL)
return;
wsprintf(szTitle, szTitleText, szTmp);
szTmp = szTitle + (lstrlen(szTitle)+2)*sizeof(TCHAR);
wvsprintf(szTmp, fmt, ap);
MessageBox(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))
LPTSTR szTitle;
LPTSTR szTmp;
LPCTSTR szTitleText = "%s Error";
LPCTSTR szDefaultModule = "TIFFLIB";
szTmp = (module == NULL) ? (LPTSTR)szDefaultModule : (LPTSTR)module;
if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (lstrlen(szTmp) +
lstrlen(szTitleText) + lstrlen(fmt) + 128)*sizeof(TCHAR))) == NULL)
return;
wsprintf(szTitle, szTitleText, szTmp);
szTmp = szTitle + (lstrlen(szTitle)+2)*sizeof(TCHAR);
wvsprintf(szTmp, fmt, ap);
MessageBox(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

View File

@ -1,76 +0,0 @@
/*
* 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
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
#ifdef WIN32
#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(long offset, int origin) = 0;
virtual long Tell() = 0;
virtual long Size() = 0;
virtual bool Flush() = 0;
virtual bool Eof() = 0;
virtual long Error() = 0;
virtual bool PutC(unsigned char c)
{
// Default implementation
size_t nWrote = Write(&c, 1, 1);
return (bool)(nWrote == 1);
}
virtual long GetC() = 0;
};
#endif //__xfile_h

View File

@ -1,361 +0,0 @@
/*
* File: ximabmp.cpp
* Purpose: Platform Independent BMP Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#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();
//copy attributes
memcpy(pDib,&head,sizeof(BITMAPINFOHEADER));
// Write the file header
hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
// Write the DIB header and the pixels
hFile->Write(pDib,GetSize(),1);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageBMP::Decode(CxFile * hFile)
{
if (hFile == NULL) return false;
BITMAPFILEHEADER bf;
DWORD off = hFile->Tell(); //<CSC>
try {
if (hFile->Read(&bf,min(14,sizeof(bf)),1)==0) throw "Not a BMP";
if (bf.bfType != BFT_BITMAP) { //do we have a RC HEADER?
bf.bfOffBits = 0L;
hFile->Seek(off,SEEK_SET);
}
BITMAPINFOHEADER bmpHeader;
if (!DibReadBitmapInfo(hFile,&bmpHeader)) throw "Error reading BMP info";
DWORD dwCompression=bmpHeader.biCompression;
DWORD 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;
throw "output dimensions returned";
}
if (!Create(bmpHeader.biWidth,bmpHeader.biHeight,bmpHeader.biBitCount,CXIMAGE_FORMAT_BMP))
throw "Can't allocate memory";
head.biXPelsPerMeter = bmpHeader.biXPelsPerMeter;
head.biYPelsPerMeter = bmpHeader.biYPelsPerMeter;
info.xDPI = (long) floor(bmpHeader.biXPelsPerMeter * 254.0 / 10000.0 + 0.5);
info.yDPI = (long) floor(bmpHeader.biYPelsPerMeter * 254.0 / 10000.0 + 0.5);
if (info.nEscape) 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 (int 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 = (BYTE)0;
}
} else {
hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
//force rgbReserved=0, to avoid problems with some WinXp bitmaps
for (unsigned int i=0; i<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
}
}
if (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding
switch (dwBitCount) {
case 32 :
if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
long imagesize=4*head.biHeight*head.biWidth;
BYTE* buff32=(BYTE*)malloc(imagesize);
if (buff32){
hFile->Read(buff32, imagesize,1); // read in the pixels
Bitfield2RGB(buff32,0,0,0,32);
free(buff32);
} else throw "can't allocate memory";
} else 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 throw "unknown compression";
break;
case 16 :
{
DWORD 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,(WORD)bfmask[0],(WORD)bfmask[1],(WORD)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 :
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
BOOL low_nibble = FALSE;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue;) {
hFile->Read(&status_byte, sizeof(BYTE), 1);
switch (status_byte) {
case RLE_COMMAND :
hFile->Read(&status_byte, sizeof(BYTE), 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
BYTE delta_x;
BYTE delta_y;
hFile->Read(&delta_x, sizeof(BYTE), 1);
hFile->Read(&delta_y, sizeof(BYTE), 1);
// apply them
bits += delta_x / 2;
scanline += delta_y;
break;
}
default :
hFile->Read(&second_byte, sizeof(BYTE), 1);
BYTE *sline = iter.GetRow(scanline);
for (int i = 0; i < status_byte; i++) {
if (low_nibble) {
if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
*(sline + bits) |= (second_byte & 0x0F);
}
if (i != status_byte - 1)
hFile->Read(&second_byte, sizeof(BYTE), 1);
bits++;
} else {
if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
*(sline + bits) = (BYTE)(second_byte & 0xF0);
}
}
low_nibble = !low_nibble;
}
if ((((status_byte+1) >> 1) & 1 )== 1)
hFile->Read(&second_byte, sizeof(BYTE), 1);
break;
};
break;
default :
{
BYTE *sline = iter.GetRow(scanline);
hFile->Read(&second_byte, sizeof(BYTE), 1);
for (unsigned i = 0; i < status_byte; i++) {
if (low_nibble) {
if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
*(sline + bits) |= (second_byte & 0x0F);
}
bits++;
} else {
if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
*(sline + bits) = (BYTE)(second_byte & 0xF0);
}
}
low_nibble = !low_nibble;
}
}
break;
};
}
break;
}
case BI_RLE8 :
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue; ) {
hFile->Read(&status_byte, sizeof(BYTE), 1);
switch (status_byte) {
case RLE_COMMAND :
hFile->Read(&status_byte, sizeof(BYTE), 1);
switch (status_byte) {
case RLE_ENDOFLINE :
bits = 0;
scanline++;
break;
case RLE_ENDOFBITMAP :
bContinue=FALSE;
break;
case RLE_DELTA :
{
// read the delta values
BYTE delta_x;
BYTE delta_y;
hFile->Read(&delta_x, sizeof(BYTE), 1);
hFile->Read(&delta_y, sizeof(BYTE), 1);
// apply them
bits += delta_x;
scanline += delta_y;
break;
}
default :
hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(BYTE) * status_byte, 1);
// align run length to even number of bytes
if ((status_byte & 1) == 1)
hFile->Read(&second_byte, sizeof(BYTE), 1);
bits += status_byte;
break;
};
break;
default :
BYTE *sline = iter.GetRow(scanline);
hFile->Read(&second_byte, sizeof(BYTE), 1);
for (unsigned i = 0; i < status_byte; i++) {
if ((DWORD)bits<info.dwEffWidth){
*(sline + bits) = second_byte;
bits++;
} else {
bContinue = FALSE;
break;
}
}
break;
};
}
break;
}
default :
throw "compression type not supported";
}
}
if (bTopDownDib) Flip(); //<Flanders>
} catch (char *message) {
strncpy(info.szLastError,message,255);
if (info.nEscape==-1) 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;
BITMAPCOREHEADER bc;
switch (pdib->biSize) // what type of bitmap info is this?
{
case sizeof(BITMAPINFOHEADER):
break;
case 64: //sizeof(OS2_BMP_HEADER):
fh->Seek((long)(64 - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
break;
case sizeof(BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER*)pdib;
pdib->biSize = bc.bcSize;
pdib->biWidth = (DWORD)bc.bcWidth;
pdib->biHeight = (DWORD)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((long)(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER)), SEEK_CUR);
break;
default:
//give a last chance
if (pdib->biSize>(sizeof(BITMAPINFOHEADER))&&
(pdib->biSizeImage==(unsigned long)(pdib->biHeight*((((pdib->biBitCount*pdib->biWidth)+31)/32)*4)))&&
(pdib->biPlanes==1)&&(pdib->biCompression==BI_RGB)&&(pdib->biClrUsed==0))
{
fh->Seek((long)(pdib->biSize - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
break;
}
return false;
}
FixBitmapInfo(pdib);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_BMP
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,79 +0,0 @@
/*
* 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 int RLE_COMMAND = 0;
const int RLE_ENDOFLINE = 0;
const int RLE_ENDOFBITMAP = 1;
const int 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) (UINT)WIDTHBYTES((UINT)(lpbi)->biWidth * (UINT)(n))
#define DibWidthBytes(lpbi) DibWidthBytesN(lpbi, (lpbi)->biBitCount)
#define DibSizeImage(lpbi) ((lpbi)->biSizeImage == 0 \
? ((DWORD)(UINT)DibWidthBytes(lpbi) * (DWORD)(UINT)(lpbi)->biHeight) \
: (lpbi)->biSizeImage)
#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
? (int)(1 << (int)(lpbi)->biBitCount) \
: (int)(lpbi)->biClrUsed)
#define FixBitmapInfo(lpbi) if ((lpbi)->biSizeImage == 0) \
(lpbi)->biSizeImage = DibSizeImage(lpbi); \
if ((lpbi)->biClrUsed == 0) \
(lpbi)->biClrUsed = DibNumColors(lpbi); \
#endif

View File

@ -1,52 +0,0 @@
#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_WINCE 0 //<T.Peck>
/////////////////////////////////////////////////////////////////////////////
// CxImage supported formats
#define CXIMAGE_SUPPORT_BMP 1
#define CXIMAGE_SUPPORT_GIF 1
#define CXIMAGE_SUPPORT_JPG 0
#define CXIMAGE_SUPPORT_PNG 0
#define CXIMAGE_SUPPORT_MNG 0
#define CXIMAGE_SUPPORT_ICO 1
#define CXIMAGE_SUPPORT_TIF 0
#define CXIMAGE_SUPPORT_TGA 1
#define CXIMAGE_SUPPORT_PCX 1
#define CXIMAGE_SUPPORT_WBMP 1
#define CXIMAGE_SUPPORT_WMF 1
#define CXIMAGE_SUPPORT_J2K 0 // Beta, use JP2
#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm
#define CXIMAGE_SUPPORT_JP2 0
#define CXIMAGE_SUPPORT_JPC 0
#define CXIMAGE_SUPPORT_PGX 0
#define CXIMAGE_SUPPORT_PNM 0
#define CXIMAGE_SUPPORT_RAS 0
/////////////////////////////////////////////////////////////////////////////
#define CXIMAGE_MAX_MEMORY 256000000
#define CXIMAGE_ERR_NOFILE "null file handler"
#define CXIMAGE_ERR_NOIMAGE "null image!!!"
/////////////////////////////////////////////////////////////////////////////
//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

View File

@ -1,197 +0,0 @@
#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_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_WINCE
#undef CXIMAGE_SUPPORT_WMF
#define CXIMAGE_SUPPORT_WMF 0
#undef CXIMAGE_SUPPORT_WINDOWS
#define CXIMAGE_SUPPORT_WINDOWS 0
#endif
#ifndef WIN32
#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
#ifdef WIN32
#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
#ifndef WIN32
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned int UINT;
typedef DWORD COLORREF;
typedef unsigned int 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
{
long left;
long top;
long right;
long bottom;
} RECT;
typedef struct tagPOINT
{
long x;
long y;
} POINT;
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
#pragma pack(1)
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
long biWidth;
long biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPCOREHEADER {
DWORD bcSize;
WORD bcWidth;
WORD bcHeight;
WORD bcPlanes;
WORD bcBitCount;
} BITMAPCOREHEADER;
typedef struct tagRGBTRIPLE {
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} RGBTRIPLE;
#pragma pack()
#define BI_RGB 0L
#define BI_RLE8 1L
#define BI_RLE4 2L
#define BI_BITFIELDS 3L
#define GetRValue(rgb) ((BYTE)(rgb))
#define GetGValue(rgb) ((BYTE)(((WORD)(rgb)) >> 8))
#define GetBValue(rgb) ((BYTE)((rgb)>>16))
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(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

File diff suppressed because it is too large Load Diff

View File

@ -1,920 +0,0 @@
// xImaCodec.cpp : Encode Decode functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_JPG
#include "ximajpg.h"
#endif
#if CXIMAGE_SUPPORT_GIF
#include "ximagif.h"
#endif
#if CXIMAGE_SUPPORT_PNG
#include "ximapng.h"
#endif
#if CXIMAGE_SUPPORT_MNG
#include "ximamng.h"
#endif
#if CXIMAGE_SUPPORT_BMP
#include "ximabmp.h"
#endif
#if CXIMAGE_SUPPORT_ICO
#include "ximaico.h"
#endif
#if CXIMAGE_SUPPORT_TIF
#include "ximatif.h"
#endif
#if CXIMAGE_SUPPORT_TGA
#include "ximatga.h"
#endif
#if CXIMAGE_SUPPORT_PCX
#include "ximapcx.h"
#endif
#if CXIMAGE_SUPPORT_WBMP
#include "ximawbmp.h"
#endif
#if CXIMAGE_SUPPORT_WMF
#include "ximawmf.h" // <vho> - WMF/EMF support
#endif
#if CXIMAGE_SUPPORT_J2K
#include "ximaj2k.h"
#endif
#if CXIMAGE_SUPPORT_JBG
#include "ximajbg.h"
#endif
#if CXIMAGE_SUPPORT_JASPER
#include "ximajas.h"
#endif
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImage::EncodeSafeCheck(CxFile *hFile)
{
if (hFile==NULL) {
strcpy(info.szLastError,CXIMAGE_ERR_NOFILE);
return true;
}
if (pDib==NULL){
strcpy(info.szLastError,CXIMAGE_ERR_NOIMAGE);
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
//#ifdef WIN32
//bool CxImage::Save(LPCWSTR filename, DWORD imagetype)
//{
// FILE* hFile; //file handle to write the image
// if ((hFile=_wfopen(filename,L"wb"))==NULL) return false;
// bool bOK = Encode(hFile,imagetype);
// fclose(hFile);
// return bOK;
//}
//#endif //WIN32
////////////////////////////////////////////////////////////////////////////////
// For UNICODE support: char -> TCHAR
/**
* Saves to disk the image in a specific format.
* \param filename: file name
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
bool CxImage::Save(const TCHAR * filename, DWORD imagetype)
{
FILE* hFile; //file handle to write the image
#ifdef WIN32
if ((hFile=_tfopen(filename,_T("wb")))==NULL) return false; // For UNICODE support
#else
if ((hFile=fopen(filename,"wb"))==NULL) return false;
#endif
bool bOK = Encode(hFile,imagetype);
fclose(hFile);
return bOK;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Saves to disk the image in a specific format.
* \param hFile: file handle, open and enabled for writing.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
bool CxImage::Encode(FILE *hFile, DWORD imagetype)
{
CxIOFile file(hFile);
return Encode(&file,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Saves to memory buffer the image in a specific format.
* \param buffer: output memory buffer pointer. Must be NULL,
* the function allocates and fill the memory,
* the application must free the buffer, see also FreeMemory().
* \param size: output memory buffer size.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
bool CxImage::Encode(BYTE * &buffer, long &size, DWORD imagetype)
{
if (buffer!=NULL){
strcpy(info.szLastError,"the buffer must be empty");
return false;
}
CxMemFile file;
file.Open();
if(Encode(&file,imagetype)){
buffer=file.GetBuffer();
size=file.Size();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Saves to disk the image in a specific format.
* \param hFile: file handle (implemented using CxMemFile or CxIOFile),
* open and enabled for writing.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
* \sa ENUM_CXIMAGE_FORMATS
*/
bool CxImage::Encode(CxFile *hFile, DWORD imagetype)
{
#if CXIMAGE_SUPPORT_BMP
if (imagetype==CXIMAGE_FORMAT_BMP){
CxImageBMP newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_ICO
if (imagetype==CXIMAGE_FORMAT_ICO){
CxImageICO newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TIF
if (imagetype==CXIMAGE_FORMAT_TIF){
CxImageTIF newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JPG
if (imagetype==CXIMAGE_FORMAT_JPG){
CxImageJPG newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_GIF
if (imagetype==CXIMAGE_FORMAT_GIF){
CxImageGIF newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PNG
if (imagetype==CXIMAGE_FORMAT_PNG){
CxImagePNG newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_MNG
if (imagetype==CXIMAGE_FORMAT_MNG){
CxImageMNG newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TGA
if (imagetype==CXIMAGE_FORMAT_TGA){
CxImageTGA newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PCX
if (imagetype==CXIMAGE_FORMAT_PCX){
CxImagePCX newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WBMP
if (imagetype==CXIMAGE_FORMAT_WBMP){
CxImageWBMP newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS // <vho> - WMF/EMF support
if (imagetype==CXIMAGE_FORMAT_WMF){
CxImageWMF newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_J2K
if (imagetype==CXIMAGE_FORMAT_J2K){
CxImageJ2K newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JBG
if (imagetype==CXIMAGE_FORMAT_JBG){
CxImageJBG newima;
newima.Ghost(this);
if (newima.Encode(hFile)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JASPER
if (
#if CXIMAGE_SUPPORT_JP2
imagetype==CXIMAGE_FORMAT_JP2 ||
#endif
#if CXIMAGE_SUPPORT_JPC
imagetype==CXIMAGE_FORMAT_JPC ||
#endif
#if CXIMAGE_SUPPORT_PGX
imagetype==CXIMAGE_FORMAT_PGX ||
#endif
#if CXIMAGE_SUPPORT_PNM
imagetype==CXIMAGE_FORMAT_PNM ||
#endif
#if CXIMAGE_SUPPORT_RAS
imagetype==CXIMAGE_FORMAT_RAS ||
#endif
false ){
CxImageJAS newima;
newima.Ghost(this);
if (newima.Encode(hFile,imagetype)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
strcpy(info.szLastError,"Encode: Unknown format");
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Saves to disk or memory pagecount images, referenced by an array of CxImage pointers.
* \param hFile: file handle.
* \param pImages: array of CxImage pointers.
* \param pagecount: number of images.
* \param imagetype: can be CXIMAGE_FORMAT_TIF or CXIMAGE_FORMAT_GIF.
* \return true if everything is ok
*/
bool CxImage::Encode(FILE * hFile, CxImage ** pImages, int pagecount, DWORD imagetype)
{
CxIOFile file(hFile);
return Encode(&file, pImages, pagecount,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Saves to disk or memory pagecount images, referenced by an array of CxImage pointers.
* \param hFile: file handle (implemented using CxMemFile or CxIOFile).
* \param pImages: array of CxImage pointers.
* \param pagecount: number of images.
* \param imagetype: can be CXIMAGE_FORMAT_TIF or CXIMAGE_FORMAT_GIF.
* \return true if everything is ok
*/
bool CxImage::Encode(CxFile * hFile, CxImage ** pImages, int pagecount, DWORD imagetype)
{
#if CXIMAGE_SUPPORT_TIF
if (imagetype==CXIMAGE_FORMAT_TIF){
CxImageTIF newima;
newima.Ghost(this);
if (newima.Encode(hFile,pImages,pagecount)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_GIF
if (imagetype==CXIMAGE_FORMAT_GIF){
CxImageGIF newima;
newima.Ghost(this);
if (newima.Encode(hFile,pImages,pagecount)){
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
strcpy(info.szLastError,"Multipage Encode, Unsupported operation for this format");
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* exports the image into a RGBA buffer, Useful for OpenGL applications.
* \param buffer: output memory buffer pointer. Must be NULL,
* the function allocates and fill the memory,
* the application must free the buffer, see also FreeMemory().
* \param size: output memory buffer size.
* \return true if everything is ok
*/
bool CxImage::Encode2RGBA(BYTE * &buffer, long &size)
{
if (buffer!=NULL){
strcpy(info.szLastError,"the buffer must be empty");
return false;
}
CxMemFile file;
file.Open();
if(Encode2RGBA(&file)){
buffer=file.GetBuffer();
size=file.Size();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* exports the image into a RGBA buffer, Useful for OpenGL applications.
* \param hFile: file handle (implemented using CxMemFile or CxIOFile).
* \return true if everything is ok
*/
bool CxImage::Encode2RGBA(CxFile *hFile)
{
if (EncodeSafeCheck(hFile)) return false;
for (DWORD y = 0; y<GetHeight(); y++) {
for(DWORD x = 0; x<GetWidth(); x++) {
RGBQUAD color = BlindGetPixelColor(x,y);
hFile->PutC(color.rgbRed);
hFile->PutC(color.rgbGreen);
hFile->PutC(color.rgbBlue);
hFile->PutC(color.rgbReserved);
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////
// For UNICODE support: char -> TCHAR
/**
* Reads from disk the image in a specific format.
* - If decoding fails using the specified image format,
* the function will try the automatic file format recognition.
*
* \param filename: file name
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
bool CxImage::Load(const TCHAR * filename, DWORD imagetype)
//bool CxImage::Load(const char * filename, DWORD imagetype)
{
/*FILE* hFile; //file handle to read the image
if ((hFile=fopen(filename,"rb"))==NULL) return false;
bool bOK = Decode(hFile,imagetype);
fclose(hFile);*/
/* automatic file type recognition */
bool bOK = false;
if ( imagetype > 0 && imagetype < CMAX_IMAGE_FORMATS ){
FILE* hFile; //file handle to read the image
#ifdef WIN32
if ((hFile=_tfopen(filename,_T("rb")))==NULL) return false; // For UNICODE support
#else
if ((hFile=fopen(filename,"rb"))==NULL) return false;
#endif
bOK = Decode(hFile,imagetype);
fclose(hFile);
if (bOK) return bOK;
}
char szError[256];
strcpy(szError,info.szLastError); //save the first error
// if failed, try automatic recognition of the file...
FILE* hFile;
#ifdef WIN32
if ((hFile=_tfopen(filename,_T("rb")))==NULL) return false; // For UNICODE support
#else
if ((hFile=fopen(filename,"rb"))==NULL) return false;
#endif
bOK = Decode(hFile,CXIMAGE_FORMAT_UNKNOWN);
fclose(hFile);
if (!bOK && imagetype > 0) strcpy(info.szLastError,szError); //restore the first error
return bOK;
}
////////////////////////////////////////////////////////////////////////////////
#ifdef WIN32
//bool CxImage::Load(LPCWSTR filename, DWORD imagetype)
//{
// /*FILE* hFile; //file handle to read the image
// if ((hFile=_wfopen(filename, L"rb"))==NULL) return false;
// bool bOK = Decode(hFile,imagetype);
// fclose(hFile);*/
//
// /* automatic file type recognition */
// bool bOK = false;
// if ( imagetype > 0 && imagetype < CMAX_IMAGE_FORMATS ){
// FILE* hFile; //file handle to read the image
// if ((hFile=_wfopen(filename,L"rb"))==NULL) return false;
// bOK = Decode(hFile,imagetype);
// fclose(hFile);
// if (bOK) return bOK;
// }
//
// char szError[256];
// strcpy(szError,info.szLastError); //save the first error
//
// // if failed, try automatic recognition of the file...
// FILE* hFile; //file handle to read the image
// if ((hFile=_wfopen(filename,L"rb"))==NULL) return false;
// bOK = Decode(hFile,CXIMAGE_FORMAT_UNKNOWN);
// fclose(hFile);
//
// if (!bOK && imagetype > 0) strcpy(info.szLastError,szError); //restore the first error
//
// return bOK;
//}
////////////////////////////////////////////////////////////////////////////////
/**
* Loads an image from the application resources.
* \param hRes: the resource handle returned by FindResource().
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS.
* \param hModule: NULL for internal resource, or external application/DLL hinstance returned by LoadLibray.
* \return true if everything is ok
*/
bool CxImage::LoadResource(HRSRC hRes, DWORD imagetype, HMODULE hModule)
{
DWORD rsize=SizeofResource(hModule,hRes);
HGLOBAL hMem=::LoadResource(hModule,hRes);
if (hMem){
char* lpVoid=(char*)LockResource(hMem);
if (lpVoid){
// FILE* fTmp=tmpfile(); doesn't work with network
/*char tmpPath[MAX_PATH] = {0};
char tmpFile[MAX_PATH] = {0};
GetTempPath(MAX_PATH,tmpPath);
GetTempFileName(tmpPath,"IMG",0,tmpFile);
FILE* fTmp=fopen(tmpFile,"w+b");
if (fTmp){
fwrite(lpVoid,rsize,1,fTmp);
fseek(fTmp,0,SEEK_SET);
bool bOK = Decode(fTmp,imagetype);
fclose(fTmp);
DeleteFile(tmpFile);
return bOK;
}*/
CxMemFile fTmp((BYTE*)lpVoid,rsize);
return Decode(&fTmp,imagetype);
}
} else strcpy(info.szLastError,"Unable to load resource!");
return false;
}
#endif //WIN32
////////////////////////////////////////////////////////////////////////////////
/**
* Constructor from file name, see Load()
* \param filename: file name
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
*/
//
// > filename: file name
// > imagetype: specify the image format (CXIMAGE_FORMAT_BMP,...)
// For UNICODE support: char -> TCHAR
CxImage::CxImage(const TCHAR * filename, DWORD imagetype)
//CxImage::CxImage(const char * filename, DWORD imagetype)
{
Startup(imagetype);
Load(filename,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Constructor from file handle, see Decode()
* \param stream: file handle, with read access.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
*/
CxImage::CxImage(FILE * stream, DWORD imagetype)
{
Startup(imagetype);
Decode(stream,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Constructor from CxFile object, see Decode()
* \param stream: file handle (implemented using CxMemFile or CxIOFile), with read access.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
*/
CxImage::CxImage(CxFile * stream, DWORD imagetype)
{
Startup(imagetype);
Decode(stream,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Constructor from memory buffer, see Decode()
* \param buffer: memory buffer
* \param size: size of buffer
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
*/
CxImage::CxImage(BYTE * buffer, DWORD size, DWORD imagetype)
{
Startup(imagetype);
CxMemFile stream(buffer,size);
Decode(&stream,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Loads an image from memory buffer
* \param buffer: memory buffer
* \param size: size of buffer
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
bool CxImage::Decode(BYTE * buffer, DWORD size, DWORD imagetype)
{
CxMemFile file(buffer,size);
return Decode(&file,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Loads an image from file handle.
* \param hFile: file handle, with read access.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
bool CxImage::Decode(FILE *hFile, DWORD imagetype)
{
CxIOFile file(hFile);
return Decode(&file,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Loads an image from CxFile object
* \param hFile: file handle (implemented using CxMemFile or CxIOFile), with read access.
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
* \sa ENUM_CXIMAGE_FORMATS
*/
bool CxImage::Decode(CxFile *hFile, DWORD imagetype)
{
if (imagetype==CXIMAGE_FORMAT_UNKNOWN){
DWORD pos = hFile->Tell();
#if CXIMAGE_SUPPORT_BMP
{ CxImageBMP newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_JPG
{ CxImageJPG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_ICO
{ CxImageICO newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_GIF
{ CxImageGIF newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_PNG
{ CxImagePNG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_TIF
{ CxImageTIF newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_MNG
{ CxImageMNG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_TGA
{ CxImageTGA newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_PCX
{ CxImagePCX newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_WBMP
{ CxImageWBMP newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
{ CxImageWMF newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_J2K
{ CxImageJ2K newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_JBG
{ CxImageJBG newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
#if CXIMAGE_SUPPORT_JASPER
{ CxImageJAS newima; newima.CopyInfo(*this); if (newima.Decode(hFile)) { Transfer(newima); return true; } else hFile->Seek(pos,SEEK_SET); }
#endif
}
#if CXIMAGE_SUPPORT_BMP
if (imagetype==CXIMAGE_FORMAT_BMP){
CxImageBMP newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JPG
if (imagetype==CXIMAGE_FORMAT_JPG){
CxImageJPG newima;
newima.CopyInfo(*this); // <ignacio>
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_ICO
if (imagetype==CXIMAGE_FORMAT_ICO){
CxImageICO newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
info.nNumFrames = newima.info.nNumFrames;
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_GIF
if (imagetype==CXIMAGE_FORMAT_GIF){
CxImageGIF newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
info.nNumFrames = newima.info.nNumFrames;
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PNG
if (imagetype==CXIMAGE_FORMAT_PNG){
CxImagePNG newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TIF
if (imagetype==CXIMAGE_FORMAT_TIF){
CxImageTIF newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
info.nNumFrames = newima.info.nNumFrames;
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_MNG
if (imagetype==CXIMAGE_FORMAT_MNG){
CxImageMNG newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
info.nNumFrames = newima.info.nNumFrames;
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_TGA
if (imagetype==CXIMAGE_FORMAT_TGA){
CxImageTGA newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_PCX
if (imagetype==CXIMAGE_FORMAT_PCX){
CxImagePCX newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WBMP
if (imagetype==CXIMAGE_FORMAT_WBMP){
CxImageWBMP newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS // vho - WMF support
if (imagetype == CXIMAGE_FORMAT_WMF){
CxImageWMF newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_J2K
if (imagetype==CXIMAGE_FORMAT_J2K){
CxImageJ2K newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JBG
if (imagetype==CXIMAGE_FORMAT_JBG){
CxImageJBG newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
#if CXIMAGE_SUPPORT_JASPER
if (
#if CXIMAGE_SUPPORT_JP2
imagetype==CXIMAGE_FORMAT_JP2 ||
#endif
#if CXIMAGE_SUPPORT_JPC
imagetype==CXIMAGE_FORMAT_JPC ||
#endif
#if CXIMAGE_SUPPORT_PGX
imagetype==CXIMAGE_FORMAT_PGX ||
#endif
#if CXIMAGE_SUPPORT_PNM
imagetype==CXIMAGE_FORMAT_PNM ||
#endif
#if CXIMAGE_SUPPORT_RAS
imagetype==CXIMAGE_FORMAT_RAS ||
#endif
false ){
CxImageJAS newima;
newima.CopyInfo(*this);
if (newima.Decode(hFile,imagetype)){
Transfer(newima);
return true;
} else {
strcpy(info.szLastError,newima.GetLastError());
return false;
}
}
#endif
strcpy(info.szLastError,"Decode: Unknown or wrong format");
return false;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_DECODE
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,873 +0,0 @@
/*
* File: ximaexif.cpp
* Purpose: EXIF reader
* 18/Aug/2002 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
* 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(int 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, int nReadMode)
{
int a;
int HaveCom = FALSE;
a = hFile->GetC();
if (a != 0xff || hFile->GetC() != M_SOI){
return FALSE;
}
for(;;){
int itemlen;
int marker = 0;
int ll,lh, got;
BYTE * 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 = (BYTE *)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] = (BYTE)lh;
Data[1] = (BYTE)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){
int 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 = (BYTE *)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((BYTE *)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(unsigned char * CharBuf, unsigned int 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 unsigned char 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;
}
int 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;
}*/
unsigned char * 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. */
// int 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.
//--------------------------------------------------------------------------
int CxImageJPG::CxExifInfo::Get16m(void * Short)
{
return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Convert a 16 bit unsigned value from file's native byte order
--------------------------------------------------------------------------*/
int CxImageJPG::CxExifInfo::Get16u(void * Short)
{
if (MotorolaOrder){
return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
}else{
return (((unsigned char *)Short)[1] << 8) | ((unsigned char *)Short)[0];
}
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Convert a 32 bit signed value from file's native byte order
--------------------------------------------------------------------------*/
long CxImageJPG::CxExifInfo::Get32s(void * Long)
{
if (MotorolaOrder){
return ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16)
| (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 );
}else{
return ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16)
| (((unsigned char *)Long)[1] << 8 ) | (((unsigned char *)Long)[0] << 0 );
}
}
////////////////////////////////////////////////////////////////////////////////
/*--------------------------------------------------------------------------
Convert a 32 bit unsigned value from file's native byte order
--------------------------------------------------------------------------*/
unsigned long CxImageJPG::CxExifInfo::Get32u(void * Long)
{
return (unsigned long)Get32s(Long) & 0xffffffff;
}
////////////////////////////////////////////////////////////////////////////////
/* Describes format descriptor */
static const int 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(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
EXIFINFO * const m_exifinfo, unsigned char ** const LastExifRefdP )
{
int de;
int a;
int NumDirEntries;
unsigned ThumbnailOffset = 0;
unsigned ThumbnailSize = 0;
NumDirEntries = Get16u(DirStart);
if ((DirStart+2+NumDirEntries*12) > (OffsetBase+ExifLength)){
strcpy(m_szLastError,"Illegally sized directory");
return false;
}
for (de=0;de<NumDirEntries;de++){
int Tag, Format, Components;
unsigned char * 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.
*/
int ByteCount;
unsigned char * 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 ((int)ConvertAnyFormat(ValuePtr, Format) & 7){
m_exifinfo->FlashUsed = 1;
}else{
m_exifinfo->FlashUsed = 0;
}
break;
case TAG_ORIENTATION:
m_exifinfo->Orientation = (int)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 = (int)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((int)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((int)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 = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_METERING_MODE:
m_exifinfo->MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_EXPOSURE_PROGRAM:
m_exifinfo->ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format);
break;
case TAG_ISO_EQUIVALENT:
m_exifinfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
break;
case TAG_COMPRESSION_LEVEL:
m_exifinfo->CompressionLevel = (int)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){
unsigned char * 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);
}
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!
*/
unsigned char * 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);
}
}
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 int, rational, or float from directory.
--------------------------------------------------------------------------*/
double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int Format)
{
double Value;
Value = 0;
switch(Format){
case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
case FMT_BYTE: Value = *(unsigned char *)ValuePtr; break;
case FMT_USHORT: Value = Get16u(ValuePtr); break;
case FMT_ULONG: Value = Get32u(ValuePtr); break;
case FMT_URATIONAL:
case FMT_SRATIONAL:
{
int 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 = (signed short)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 BYTE * Data, int length)
{
int ch;
char Comment[MAX_COMMENT+1];
int nch;
int 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 BYTE * Data, int marker)
{
int 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)
{
int 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 BYTE 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(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;
int 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(int SectionType)
{
int 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

View File

@ -1,498 +0,0 @@
// ximage.cpp : main implementation file
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
// CxImage
////////////////////////////////////////////////////////////////////////////////
/**
* Initialize the internal structures
*/
void CxImage::Startup(DWORD imagetype)
{
//init pointers
pDib = pSelection = pAlpha = NULL;
pLayers = NULL;
//init structures
memset(&head,0,sizeof(BITMAPINFOHEADER));
memset(&info,0,sizeof(CXIMAGEINFO));
//init default attributes
info.dwType = imagetype;
info.nQuality = 90;
info.nAlphaMax = 255;
info.nBkgndIndex = -1;
info.bEnabled = true;
SetXDPI(96);
SetYDPI(96);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Empty image constructor
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
*/
CxImage::CxImage(DWORD 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 (pLayers) {
for(long n=0; n<info.nNumLayers;n++){ delete pLayers[n]; }
free(pLayers); pLayers=0;
}
if (pSelection) {free(pSelection); pSelection=0;}
if (pAlpha) {free(pAlpha); pAlpha=0;}
if (pDib) {free(pDib); pDib=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(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD 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)
{
//copy the attributes
memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
//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());
long nSize = head.biWidth * head.biHeight;
//copy the selection
if (copyselection && src.pSelection){
if (pSelection) free(pSelection);
pSelection = (BYTE*)malloc(nSize);
memcpy(pSelection,src.pSelection,nSize);
}
//copy the alpha channel
if (copyalpha && src.pAlpha){
if (pAlpha) free(pAlpha);
pAlpha = (BYTE*)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(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD 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 (and also a check for bad parameters)
if (((dwWidth*dwHeight*wBpp)>>8) > 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 = (WORD)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;
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>
*/
BYTE* CxImage::GetBits(DWORD row)
{
if (pDib){
if (row) {
if (row<(DWORD)head.biHeight){
return ((BYTE*)pDib + *(DWORD*)pDib + GetPaletteSize() + (info.dwEffWidth * row));
} else {
return NULL;
}
} else {
return ((BYTE*)pDib + *(DWORD*)pDib + GetPaletteSize());
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return the size in bytes of the internal pDib object
*/
long 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(long x, long 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(BYTE bval)
{
if (pDib == 0) return;
if (GetBpp() == 1){
if (bval > 0) bval = 255;
}
if (GetBpp() == 4){
bval = (BYTE)(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)
{
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;
pLayers = from.pLayers;
memset(&from.head,0,sizeof(BITMAPINFOHEADER));
memset(&from.info,0,sizeof(CXIMAGEINFO));
from.pDib = from.pSelection = from.pAlpha = NULL;
from.pLayers = 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(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;
pLayers = from->pLayers;
info.pGhost=from;
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* turns a 16 or 32 bit bitfield image into a RGB image
*/
void CxImage::Bitfield2RGB(BYTE *src, WORD redmask, WORD greenmask, WORD bluemask, BYTE bpp)
{
switch (bpp){
case 16:
{
DWORD ns[3]={0,0,0};
// compute the number of shift for each mask
for (int 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
long effwidth2=(((head.biWidth + 1) / 2) * 4);
WORD w;
long y2,y3,x2,x3;
BYTE *p=info.pImage;
// scan the buffer in reverse direction to avoid reallocations
for (long y=head.biHeight-1; y>=0; y--){
y2=effwidth2*y;
y3=info.dwEffWidth*y;
for (long x=head.biWidth-1; x>=0; x--){
x2 = 2*x+y2;
x3 = 3*x+y3;
w = (WORD)(src[x2]+256*src[1+x2]);
p[ x3]=(BYTE)((w & bluemask)<<ns[0]);
p[1+x3]=(BYTE)((w & greenmask)>>ns[1]);
p[2+x3]=(BYTE)((w & redmask)>>ns[2]);
}
}
break;
}
case 32:
{
// dword aligned width for 32 bit image
long effwidth4 = head.biWidth * 4;
long y4,y3,x4,x3;
BYTE *p=info.pImage;
// scan the buffer in reverse direction to avoid reallocations
for (long y=head.biHeight-1; y>=0; y--){
y4=effwidth4*y;
y3=info.dwEffWidth*y;
for (long x=head.biWidth-1; x>=0; x--){
x4 = 4*x+y4;
x3 = 3*x+y3;
p[ x3]=src[ x4];
p[1+x3]=src[1+x4];
p[2+x3]=src[2+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(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD 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
BYTE *dst,*src;
for (DWORD y = 0; y<dwHeight; y++) {
dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
src = pArray + y * dwBytesperline;
if (dwBitsperpixel==32){
for(DWORD x=0;x<dwWidth;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;
}
} else {
memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa CreateFromArray
*/
bool CxImage::CreateFromMatrix(BYTE** ppMatrix,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD 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
BYTE *dst,*src;
for (DWORD y = 0; y<dwHeight; y++) {
dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
src = ppMatrix[y];
if (src){
if (dwBitsperpixel==32){
for(DWORD x=0;x<dwWidth;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;
}
} else {
memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return lightness difference between elem1 and elem2
*/
int CxImage::CompareColors(const void *elem1, const void *elem2)
{
RGBQUAD* c1 = (RGBQUAD*)elem1;
RGBQUAD* c2 = (RGBQUAD*)elem2;
int g1 = (int)RGB2GRAY(c1->rgbRed,c1->rgbGreen,c1->rgbBlue);
int g2 = (int)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.
*/
void CxImage::FreeMemory(void* memblock)
{
if (memblock)
free(memblock);
}
////////////////////////////////////////////////////////////////////////////////
//EOF

View File

@ -1,648 +0,0 @@
/*
* File: ximage.h
* Purpose: General Purpose Image Class
*/
/*
--------------------------------------------------------------------------------
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
CxImage version 5.99c 17/Oct/2004
CxImage : Copyright (C) 2001 - 2004, 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
--------------------------------------------------------------------------------
*/
#if !defined(__CXIMAGE_H)
#define __CXIMAGE_H
#if _MSC_VER > 1000
#pragma once
#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,
#if CXIMAGE_SUPPORT_BMP
CXIMAGE_FORMAT_BMP,
#endif
#if CXIMAGE_SUPPORT_GIF
CXIMAGE_FORMAT_GIF,
#endif
#if CXIMAGE_SUPPORT_JPG
CXIMAGE_FORMAT_JPG,
#endif
#if CXIMAGE_SUPPORT_PNG
CXIMAGE_FORMAT_PNG,
#endif
#if CXIMAGE_SUPPORT_MNG
CXIMAGE_FORMAT_MNG,
#endif
#if CXIMAGE_SUPPORT_ICO
CXIMAGE_FORMAT_ICO,
#endif
#if CXIMAGE_SUPPORT_TIF
CXIMAGE_FORMAT_TIF,
#endif
#if CXIMAGE_SUPPORT_TGA
CXIMAGE_FORMAT_TGA,
#endif
#if CXIMAGE_SUPPORT_PCX
CXIMAGE_FORMAT_PCX,
#endif
#if CXIMAGE_SUPPORT_WBMP
CXIMAGE_FORMAT_WBMP,
#endif
#if CXIMAGE_SUPPORT_WMF
CXIMAGE_FORMAT_WMF,
#endif
#if CXIMAGE_SUPPORT_J2K
CXIMAGE_FORMAT_J2K,
#endif
#if CXIMAGE_SUPPORT_JBG
CXIMAGE_FORMAT_JBG,
#endif
#if CXIMAGE_SUPPORT_JP2
CXIMAGE_FORMAT_JP2,
#endif
#if CXIMAGE_SUPPORT_JPC
CXIMAGE_FORMAT_JPC,
#endif
#if CXIMAGE_SUPPORT_PGX
CXIMAGE_FORMAT_PGX,
#endif
#if CXIMAGE_SUPPORT_PNM
CXIMAGE_FORMAT_PNM,
#endif
#if CXIMAGE_SUPPORT_RAS
CXIMAGE_FORMAT_RAS,
#endif
CMAX_IMAGE_FORMATS
};
/////////////////////////////////////////////////////////////////////////////
// CxImage class
/////////////////////////////////////////////////////////////////////////////
class DLL_EXP CxImage
{
//extensible information collector
typedef struct tagCxImageInfo {
DWORD dwEffWidth; ///< DWORD aligned scan line width
BYTE* 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
DWORD dwType; ///< original image format
char szLastError[256]; ///< debugging
long nProgress; ///< monitor
long nEscape; ///< escape
long nBkgndIndex; ///< used for GIF, PNG, MNG
RGBQUAD nBkgndColor; ///< used for RGB transparency
BYTE nQuality; ///< used for JPEG
BYTE nJpegScale; ///< used for JPEG [ignacio]
long nFrame; ///< used for TIF, GIF, MNG : actual frame
long nNumFrames; ///< used for TIF, GIF, MNG : total number of frames
DWORD dwFrameDelay; ///< used for GIF, MNG
long xDPI; ///< horizontal resolution
long yDPI; ///< vertical resolution
RECT rSelectionBox; ///< bounding rectangle
BYTE nAlphaMax; ///< max opacity (fade)
bool bAlphaPaletteEnabled; ///< true if alpha values in the palette are enabled.
bool bEnabled; ///< enables the painting functions
long xOffset;
long yOffset;
DWORD 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
BYTE last_c_index;
bool last_c_isvalid;
long nNumLayers;
DWORD dwFlags; ///< 0x??00000 = reserved, 0x00??0000 = blend mode, 0x0000???? = layer id - user flags
} CXIMAGEINFO;
public:
//public structures
struct rgb_color { BYTE r,g,b; };
#if CXIMAGE_SUPPORT_WINDOWS
// <VATI> text placement data
// members must be initialized with the InitTextInfo(&this) function.
typedef struct tagCxTextInfo
{
TCHAR text[4096]; ///< text (char -> TCHAR for UNICODE [Cesar M])
LOGFONT lfont; ///< font and codepage data
COLORREF fcolor; ///< foreground color
long align; ///< DT_CENTER, DT_RIGHT, DT_LEFT aligment for multiline text
BYTE 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)
BYTE b_outline; ///< outline width for background (zero: no outline)
BYTE 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(DWORD imagetype = 0);
CxImage(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0);
CxImage(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
CxImage(const TCHAR * filename, DWORD imagetype); // For UNICODE support: char -> TCHAR
CxImage(FILE * stream, DWORD imagetype);
CxImage(CxFile * stream, DWORD imagetype);
CxImage(BYTE * buffer, DWORD size, DWORD imagetype);
virtual ~CxImage() { Destroy(); };
CxImage& operator = (const CxImage&);
//@}
/** \addtogroup Initialization */ //@{
void* Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0);
bool Destroy();
void Clear(BYTE bval=0);
void Copy(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
bool Transfer(CxImage &from);
bool CreateFromArray(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage);
bool CreateFromMatrix(BYTE** ppMatrix,DWORD dwWidth,DWORD dwHeight,DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage);
void FreeMemory(void* memblock);
//@}
/** \addtogroup Attributes */ //@{
long GetSize();
BYTE* GetBits(DWORD row = 0);
BYTE GetColorType();
void* GetDIB() const;
DWORD GetHeight() const;
DWORD GetWidth() const;
DWORD GetEffWidth() const;
DWORD GetNumColors() const;
WORD GetBpp() const;
DWORD GetType() const;
const char* GetLastError();
const TCHAR* GetVersion();
const float GetVersionNumber();
DWORD GetFrameDelay() const;
void SetFrameDelay(DWORD d);
void GetOffset(long *x,long *y);
void SetOffset(long x,long y);
BYTE GetJpegQuality() const;
void SetJpegQuality(BYTE q);
BYTE GetJpegScale() const;
void SetJpegScale(BYTE q);
long GetXDPI() const;
long GetYDPI() const;
void SetXDPI(long dpi);
void SetYDPI(long dpi);
DWORD GetClrImportant() const;
void SetClrImportant(DWORD ncolors = 0);
long GetProgress() const;
long GetEscape() const;
void SetProgress(long p);
void SetEscape(long i);
long GetTransIndex() const;
RGBQUAD GetTransColor();
void SetTransIndex(long idx);
void SetTransColor(RGBQUAD rgb);
bool IsTransparent() const;
DWORD GetCodecOption(DWORD imagetype = 0);
bool SetCodecOption(DWORD opt, DWORD imagetype = 0);
DWORD GetFlags() const;
void SetFlags(DWORD flags, bool bLockReservedFlags = true);
//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);
DWORD GetPaletteSize();
RGBQUAD* GetPalette() const;
RGBQUAD GetPaletteColor(BYTE idx);
bool GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b);
BYTE GetNearestIndex(RGBQUAD c);
void BlendPalette(COLORREF cr,long perc);
void SetGrayPalette();
void SetPalette(DWORD n, BYTE *r, BYTE *g, BYTE *b);
void SetPalette(RGBQUAD* pPal,DWORD nColors=256);
void SetPalette(rgb_color *rgb,DWORD nColors=256);
void SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha=0);
void SetPaletteColor(BYTE idx, RGBQUAD c);
void SetPaletteColor(BYTE idx, COLORREF cr);
void SwapIndex(BYTE idx1, BYTE idx2);
void SetStdPalette();
//@}
/** \addtogroup Pixel */ //@{
bool IsInside(long x, long y);
bool IsTransparent(long x,long y);
RGBQUAD GetPixelColor(long x,long y, bool bGetAlpha = true);
BYTE GetPixelIndex(long x,long y);
BYTE GetPixelGray(long x, long y);
void SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha = false);
void SetPixelColor(long x,long y,COLORREF cr);
void SetPixelIndex(long x,long y,BYTE i);
void DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha=false);
void DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr);
void BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha = false);
//@}
protected:
/** \addtogroup Protected */ //@{
BYTE BlindGetPixelIndex(const long x,const long y);
RGBQUAD BlindGetPixelColor(const long x,const long y);
void *BlindGetPixelPointer(const long x,const long y);
//@}
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(long &x, long &y, OverflowMethod const ofMethod);
RGBQUAD GetPixelColorWithOverflow(long x, long 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
};
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);
//@}
#endif //CXIMAGE_SUPPORT_INTERPOLATION
/** \addtogroup Painting */ //@{
#if CXIMAGE_SUPPORT_WINCE
long Blt(HDC pDC, long x=0, long y=0);
#endif
#if CXIMAGE_SUPPORT_WINDOWS
HBITMAP MakeBitmap(HDC hdc = NULL);
HANDLE CopyToHandle();
bool CreateFromHANDLE(HANDLE hMem); //Windows objects (clipboard)
bool CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0); //Windows resource
bool CreateFromHICON(HICON hico);
long Draw(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1, RECT* pClipRect = 0, bool bSmooth = false);
long Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false);
long Stretch(HDC hdc, long xoffset, long yoffset, long xsize, long ysize, DWORD dwRop = SRCCOPY);
long Stretch(HDC hdc, const RECT& rect, DWORD dwRop = SRCCOPY);
long Tile(HDC hdc, RECT *rc);
long Draw2(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1);
long Draw2(HDC hdc, const RECT& rect);
//long DrawString(HDC hdc, long x, long y, const char* text, RGBQUAD color, const char* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false);
long DrawString(HDC hdc, long x, long y, const TCHAR* text, RGBQUAD color, const TCHAR* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false);
// <VATI> extensions
long DrawStringEx(HDC hdc, long x, long y, CXTEXTINFO *pTextType, bool bSetAlpha=false );
void InitTextInfo( CXTEXTINFO *txt );
#endif //CXIMAGE_SUPPORT_WINDOWS
//@}
// file operations
#if CXIMAGE_SUPPORT_DECODE
/** \addtogroup Decode */ //@{
#ifdef WIN32
//bool Load(LPCWSTR filename, DWORD imagetype=0);
bool LoadResource(HRSRC hRes, DWORD imagetype, HMODULE hModule=NULL);
#endif
// For UNICODE support: char -> TCHAR
bool Load(const TCHAR* filename, DWORD imagetype=0);
//bool Load(const char * filename, DWORD imagetype=0);
bool Decode(FILE * hFile, DWORD imagetype);
bool Decode(CxFile * hFile, DWORD imagetype);
bool Decode(BYTE * buffer, DWORD size, DWORD imagetype);
//@}
#endif //CXIMAGE_SUPPORT_DECODE
#if CXIMAGE_SUPPORT_ENCODE
protected:
/** \addtogroup Protected */ //@{
bool EncodeSafeCheck(CxFile *hFile);
//@}
public:
/** \addtogroup Encode */ //@{
#ifdef WIN32
//bool Save(LPCWSTR filename, DWORD imagetype=0);
#endif
// For UNICODE support: char -> TCHAR
bool Save(const TCHAR* filename, DWORD imagetype);
//bool Save(const char * filename, DWORD imagetype=0);
bool Encode(FILE * hFile, DWORD imagetype);
bool Encode(CxFile * hFile, DWORD imagetype);
bool Encode(CxFile * hFile, CxImage ** pImages, int pagecount, DWORD imagetype);
bool Encode(FILE *hFile, CxImage ** pImages, int pagecount, DWORD imagetype);
bool Encode(BYTE * &buffer, long &size, DWORD imagetype);
bool Encode2RGBA(CxFile *hFile);
bool Encode2RGBA(BYTE * &buffer, long &size);
//@}
#endif //CXIMAGE_SUPPORT_ENCODE
/** \addtogroup Attributes */ //@{
//misc.
bool IsValid() const;
bool IsEnabled() const;
void Enable(bool enable=true);
// frame operations
long GetNumFrames() const;
long GetFrame() const;
void SetFrame(long nFrame);
//@}
#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
/** \addtogroup BasicTransformations */ //@{
bool GrayScale();
bool Flip();
bool Mirror();
bool Negative();
bool RotateLeft(CxImage* iDst = NULL);
bool RotateRight(CxImage* iDst = NULL);
//@}
#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(long newx, long newy, int mode = 1, CxImage* iDst = NULL);
bool Resample2(long newx, long newy, InterpolationMethod const inMethod=IM_BICUBIC2,
OverflowMethod const ofMethod=OM_REPEAT, CxImage* const iDst = NULL,
bool const disableAveraging=false);
bool DecreaseBpp(DWORD nbit, bool errordiffusion, RGBQUAD* ppal = 0, DWORD clrimportant = 0);
bool IncreaseBpp(DWORD nbit);
bool Dither(long method = 0);
bool Crop(long left, long top, long right, long bottom, CxImage* iDst = NULL);
bool Crop(const RECT& rect, CxImage* iDst = NULL);
bool CropRotatedRectangle( long topx, long topy, long width, long height, float angle, CxImage* iDst = NULL);
bool Skew(float xgain, float ygain, long xpivot=0, long ypivot=0, bool bEnableInterpolation = false);
bool Expand(long left, long top, long right, long bottom, RGBQUAD canvascolor, CxImage* iDst = 0);
bool Expand(long newx, long newy, RGBQUAD canvascolor, CxImage* iDst = 0);
bool Thumbnail(long newx, long newy, RGBQUAD canvascolor, CxImage* iDst = 0);
bool CircleTransform(int type,long rmax=0,float Koeff=1.0f);
bool RedEyeRemove();
bool QIShrink(long newx, long newy, CxImage* const iDst = NULL);
//@}
#endif //CXIMAGE_SUPPORT_TRANSFORMATION
#if CXIMAGE_SUPPORT_DSP
/** \addtogroup DSP */ //@{
bool Contour();
bool HistogramStretch(long method = 0);
bool HistogramEqualize();
bool HistogramNormalize();
bool HistogramRoot();
bool HistogramLog();
long Histogram(long* red, long* green = 0, long* blue = 0, long* gray = 0, long colorspace = 0);
bool Jitter(long radius=2);
bool Repair(float radius = 0.25f, long niterations = 1, long colorspace = 0);
bool Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, long colorspace = 0);
bool FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag, long direction = 1, bool bForceFFT = true, bool bMagnitude = true);
bool Noise(long level);
bool Median(long Ksize=3);
bool Gamma(float gamma);
bool ShiftRGB(long r, long g, long b);
bool Threshold(BYTE level);
bool Colorize(BYTE hue, BYTE sat, float blend = 1.0f);
bool Light(long brightness, long contrast = 0);
float Mean();
bool Filter(long* kernel, long Ksize, long Kfactor, long Koffset);
bool Erode(long Ksize=2);
bool Dilate(long Ksize=2);
bool Edge(long Ksize=2);
void HuePalette(float correction=1);
enum ImageOpType { OpAdd, OpAnd, OpXor, OpOr, OpMask, OpSrcCopy, OpDstCopy, OpSub, OpSrcBlend, OpScreen };
void Mix(CxImage & imgsrc2, ImageOpType op, long lXOffset = 0, long lYOffset = 0, bool bMixAlpha = false);
void MixFrom(CxImage & imagesrc2, long lXOffset, long lYOffset);
bool UnsharpMask(float radius = 5.0, float amount = 0.5, int threshold = 0);
bool Lut(BYTE* pLut);
bool Lut(BYTE* pLutR, BYTE* pLutG, BYTE* pLutB, BYTE* pLutA = 0);
//@}
protected:
/** \addtogroup Protected */ //@{
bool IsPowerof2(long x);
bool FFT(int dir,int m,double *x,double *y);
bool DFT(int dir,long m,double *x1,double *y1,double *x2,double *y2);
bool RepairChannel(CxImage *ch, float radius);
// <nipper>
int gen_convolve_matrix (float radius, float **cmatrix_p);
float* gen_lookup_table (float *cmatrix, int cmatrix_length);
void blur_line (float *ctable, float *cmatrix, int cmatrix_length, BYTE* cur_col, BYTE* dest_col, int y, long 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);
//@}
#if CXIMAGE_SUPPORT_SELECTION
/** \addtogroup Selection */ //@{
bool SelectionClear();
bool SelectionCreate();
bool SelectionDelete();
bool SelectionInvert();
bool SelectionAddRect(RECT r);
bool SelectionAddEllipse(RECT r);
bool SelectionAddPolygon(POINT *points, long npoints);
bool SelectionAddColor(RGBQUAD c);
bool SelectionAddPixel(int x, int y);
bool SelectionCopy(CxImage &from);
bool SelectionIsInside(long x, long y);
bool SelectionIsValid();
void SelectionGetBox(RECT& r);
bool SelectionToHRGN(HRGN& region);
bool SelectionSplit(CxImage *dest);
//@}
#endif //CXIMAGE_SUPPORT_SELECTION
#if CXIMAGE_SUPPORT_ALPHA
/** \addtogroup Alpha */ //@{
void AlphaClear();
void AlphaCreate();
void AlphaDelete();
void AlphaInvert();
bool AlphaMirror();
bool AlphaFlip();
bool AlphaCopy(CxImage &from);
bool AlphaSplit(CxImage *dest);
void AlphaStrip();
void AlphaSet(BYTE level);
bool AlphaSet(CxImage &from);
void AlphaSet(const long x,const long y,const BYTE level);
BYTE AlphaGet(const long x,const long y);
BYTE AlphaGetMax() const;
void AlphaSetMax(BYTE nAlphaMax);
bool AlphaIsValid();
BYTE* AlphaGetPointer(const long x = 0,const long y = 0);
void AlphaPaletteClear();
void AlphaPaletteEnable(bool enable=true);
bool AlphaPaletteIsEnabled();
bool AlphaPaletteIsValid();
bool AlphaPaletteSplit(CxImage *dest);
//@}
protected:
/** \addtogroup Protected */ //@{
BYTE BlindAlphaGet(const long x,const long y);
//@}
#endif //CXIMAGE_SUPPORT_ALPHA
public:
#if CXIMAGE_SUPPORT_LAYERS
/** \addtogroup Layers */ //@{
bool LayerCreate(long position = -1);
bool LayerDelete(long position = -1);
void LayerDeleteAll();
CxImage* GetLayer(long position);
CxImage* GetParent() const;
long GetNumLayers() const;
//@}
#endif //CXIMAGE_SUPPORT_LAYERS
protected:
/** \addtogroup Protected */ //@{
void Startup(DWORD imagetype = 0);
void CopyInfo(const CxImage &src);
void Ghost(CxImage *src);
void RGBtoBGR(BYTE *buffer, int length);
static float HueToRGB(float n1,float n2, float hue);
void Bitfield2RGB(BYTE *src, WORD redmask, WORD greenmask, WORD bluemask, BYTE bpp);
static int CompareColors(const void *elem1, const void *elem2);
void* pDib; //contains the header, the palette, the pixels
BITMAPINFOHEADER head; //standard header
CXIMAGEINFO info; //extended information
BYTE* pSelection; //selected region
BYTE* pAlpha; //alpha channel
CxImage** pLayers; //generic layers
//@}
};
////////////////////////////////////////////////////////////////////////////
#endif // !defined(__CXIMAGE_H)

File diff suppressed because it is too large Load Diff

View File

@ -1,248 +0,0 @@
/*
* 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 short int 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 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{
BYTE transpcolflag:1;
BYTE userinputflag:1;
BYTE dispmeth:3;
BYTE res:3;
WORD delaytime;
BYTE transpcolindex;
} struct_gifgce;
typedef struct tag_dscgif{ /* Logic Screen Descriptor */
char header[6]; /* Firma and version */
WORD scrwidth;
WORD scrheight;
char pflds;
char bcindx;
char pxasrat;
} struct_dscgif;
typedef struct tag_image{ /* Image Descriptor */
WORD l;
WORD t;
WORD w;
WORD h;
BYTE pf;
} struct_image;
typedef struct tag_TabCol{ /* Tabla de colores */
short colres; /* color resolution */
short sogct; /* size of global color table */
rgb_color paleta[256]; /* paleta */
} struct_TabCol;
typedef struct tag_RLE{
int rl_pixel;
int rl_basecode;
int rl_count;
int rl_table_pixel;
int rl_table_max;
int just_cleared;
int out_bits;
int out_bits_init;
int out_count;
int out_bump;
int out_bump_init;
int out_clear;
int out_clear_init;
int max_ocodes;
int code_clear;
int code_eof;
unsigned int obuf;
int obits;
unsigned char oblock[256];
int oblen;
} struct_RLE;
#pragma pack()
public:
CxImageGIF(): CxImage(CXIMAGE_FORMAT_GIF) {m_loops=0; m_dispmeth=0; m_comment[0]='\0';}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_GIF);}
// bool Save(const char * 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, int pagecount, bool bLocalColorMap = false);
bool Encode(FILE *fp) { CxIOFile file(fp); return Encode(&file); }
bool Encode(FILE *fp, CxImage ** pImages, int pagecount, bool bLocalColorMap = false)
{ CxIOFile file(fp); return Encode(&file, pImages, pagecount, bLocalColorMap); }
#endif // CXIMAGE_SUPPORT_ENCODE
void SetLoops(int loops);
long GetLoops();
void SetComment(const char* sz_comment_in);
void GetComment(char* sz_comment_out);
void SetDisposalMethod(int dm);
long GetDisposalMethod();
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;
int curx, cury;
long CountDown;
unsigned long cur_accum;
int cur_bits;
int interlaced, iypos, istep, iheight, ipass;
int ibf;
int ibfmax;
BYTE buf[GIFBUFTAM + 1];
// Implementation
int GifNextPixel ();
void Putword (int w, CxFile* fp );
void compressNONE (int init_bits, CxFile* outfile);
void compressLZW (int init_bits, CxFile* outfile);
void output (code_int code );
void cl_hash (long hsize);
void char_out (int c);
void flush_char ();
short init_exp(short size);
short get_next_code(CxFile*);
short decoder(CxFile*, CImageIterator* iter, short linewidth, int &bad_code_count);
int get_byte(CxFile*);
int out_line(CImageIterator* iter, unsigned char *pixels, int linelen);
int get_num_frames(CxFile *f,struct_TabCol* TabColSrc,struct_dscgif* dscgif);
long seek_next_image(CxFile* fp, long position);
short curr_size; /* The current code size */
short clear; /* Value for a clear code */
short ending; /* Value for a ending code */
short newcodes; /* First available code */
short top_slot; /* Highest code for current size */
short slot; /* Last read code */
/* The following static variables are used
* for seperating out codes */
short navail_bytes; /* # bytes left in block */
short nbits_left; /* # bits left in current BYTE */
BYTE b1; /* Current BYTE */
BYTE byte_buff[257]; /* Current block */
BYTE *pbytes; /* Pointer to next BYTE 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...)
*/
BYTE stack[MAX_CODES + 1]; /* Stack for storing pixels */
BYTE suffix[MAX_CODES + 1]; /* Suffix table */
WORD prefix[MAX_CODES + 1]; /* Prefix linked list */
//LZW GIF Image compression routines
long htab [HSIZE];
unsigned short codetab [HSIZE];
int n_bits; /* number of bits/code */
code_int maxcode; /* maximum code, given n_bits */
code_int free_ent; /* first unused entry */
int clear_flg;
int g_init_bits;
CxFile* g_outfile;
int ClearCode;
int EOFCode;
int a_count;
char accum[256];
char m_comment[256];
int m_loops;
int m_dispmeth;
//RLE compression routines
void compressRLE( int init_bits, CxFile* outfile);
void rle_clear(struct_RLE* rle);
void rle_flush(struct_RLE* rle);
void rle_flush_withtable(int count, struct_RLE* rle);
void rle_flush_clearorrep(int count, struct_RLE* rle);
void rle_flush_fromclear(int count,struct_RLE* rle);
void rle_output_plain(int c,struct_RLE* rle);
void rle_reset_out_clear(struct_RLE* rle);
unsigned int rle_compute_triangle_count(unsigned int count, unsigned int nrepcodes);
unsigned int rle_isqrt(unsigned int x);
void rle_write_block(struct_RLE* rle);
void rle_block_out(unsigned char c, struct_RLE* rle);
void rle_block_flush(struct_RLE* rle);
void rle_output(int val, struct_RLE* rle);
void rle_output_flush(struct_RLE* rle);
};
#endif
#endif

View File

@ -1,649 +0,0 @@
// xImaHist.cpp : histogram functions
/* 28/01/2004 v1.00 - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_DSP
////////////////////////////////////////////////////////////////////////////////
long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace)
{
if (!pDib) return 0;
RGBQUAD color;
if (red) memset(red,0,256*sizeof(long));
if (green) memset(green,0,256*sizeof(long));
if (blue) memset(blue,0,256*sizeof(long));
if (gray) memset(gray,0,256*sizeof(long));
long 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(long y=ymin; y<ymax; y++){
for(long x=xmin; x<xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
{
switch (colorspace){
case 1:
color = HSLtoRGB(GetPixelColor(x,y));
break;
case 2:
color = YUVtoRGB(GetPixelColor(x,y));
break;
case 3:
color = YIQtoRGB(GetPixelColor(x,y));
break;
case 4:
color = XYZtoRGB(GetPixelColor(x,y));
break;
default:
color = GetPixelColor(x,y);
}
if (red) red[color.rgbRed]++;
if (green) green[color.rgbGreen]++;
if (blue) blue[color.rgbBlue]++;
if (gray) gray[(BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
}
}
}
long n=0;
for (int 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.
* \return true if everything is ok
* \author [dave] and [nipper]
*/
bool CxImage::HistogramStretch(long method)
{
if (!pDib) return false;
if ((head.biBitCount==8) && IsGrayScale()){
// get min/max info
BYTE minc = 255, maxc = 0;
BYTE gray;
long y;
double dbScaler = 50.0/head.biHeight;
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++) {
gray = GetPixelIndex(x, y);
if (gray < minc) minc = gray;
if (gray > maxc) maxc = gray;
}
}
if (minc == 0 && maxc == 255) return true;
// calculate LUT
BYTE lut[256];
BYTE range = maxc - minc;
if (range != 0){
for (long x = minc; x <= maxc; x++){
lut[x] = (BYTE)(255 * (x - minc) / range);
}
} else lut[minc] = minc;
for (y=0; y<head.biHeight; y++) {
if (info.nEscape) break;
info.nProgress = (long)(50.0+y*dbScaler);
for (long x=0; x<head.biWidth; x++)
{
SetPixelIndex(x, y, lut[GetPixelIndex(x, y)]);
}
}
} else {
switch(method){
case 1:
{ // <nipper>
// get min/max info
BYTE minc = 255, maxc = 0;
RGBQUAD color;
long y;
for (y=0; y<head.biHeight; y++)
{
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
if (color.rgbRed < minc) minc = color.rgbRed;
if (color.rgbBlue < minc) minc = color.rgbBlue;
if (color.rgbGreen < minc) minc = color.rgbGreen;
if (color.rgbRed > maxc) maxc = color.rgbRed;
if (color.rgbBlue > maxc) maxc = color.rgbBlue;
if (color.rgbGreen > maxc) maxc = color.rgbGreen;
}
}
if (minc == 0 && maxc == 255)
return true;
// calculate LUT
BYTE lut[256];
BYTE range = maxc - minc;
if (range != 0){
for (long x = minc; x <= maxc; x++){
lut[x] = (BYTE)(255 * (x - minc) / range);
}
} else lut[minc] = minc;
// normalize image
double dbScaler = 100.0/head.biHeight;
for (y=0; y<head.biHeight; y++) {
if (info.nEscape) break;
info.nProgress = (long)(y*dbScaler);
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
color.rgbRed = lut[color.rgbRed];
color.rgbBlue = lut[color.rgbBlue];
color.rgbGreen = lut[color.rgbGreen];
SetPixelColor(x, y, color);
}
}
}
break;
case 2:
{ // <nipper>
// get min/max info
BYTE minR = 255, maxR = 0;
BYTE minG = 255, maxG = 0;
BYTE minB = 255, maxB = 0;
RGBQUAD color;
long y;
for (y=0; y<head.biHeight; y++)
{
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
if (color.rgbRed < minR) minR = color.rgbRed;
if (color.rgbBlue < minB) minB = color.rgbBlue;
if (color.rgbGreen < minG) minG = color.rgbGreen;
if (color.rgbRed > maxR) maxR = color.rgbRed;
if (color.rgbBlue > maxB) maxB = color.rgbBlue;
if (color.rgbGreen > maxG) maxG = color.rgbGreen;
}
}
if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
return true;
// calculate LUT
BYTE lutR[256];
BYTE range = maxR - minR;
if (range != 0) {
for (long x = minR; x <= maxR; x++){
lutR[x] = (BYTE)(255 * (x - minR) / range);
}
} else lutR[minR] = minR;
BYTE lutG[256];
range = maxG - minG;
if (range != 0) {
for (long x = minG; x <= maxG; x++){
lutG[x] = (BYTE)(255 * (x - minG) / range);
}
} else lutG[minG] = minG;
BYTE lutB[256];
range = maxB - minB;
if (range != 0) {
for (long x = minB; x <= maxB; x++){
lutB[x] = (BYTE)(255 * (x - minB) / range);
}
} else lutB[minB] = minB;
// normalize image
double dbScaler = 100.0/head.biHeight;
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
color.rgbRed = lutR[color.rgbRed];
color.rgbBlue = lutB[color.rgbBlue];
color.rgbGreen = lutG[color.rgbGreen];
SetPixelColor(x, y, color);
}
}
}
break;
default:
{ // <dave>
// S = ( R - C ) ( B - A / D - C )
double alimit = 0.0;
double blimit = 255.0;
double lowerc = 255.0;
double upperd = 0.0;
double tmpGray;
RGBQUAD color;
RGBQUAD yuvClr;
double stretcheds;
if ( head.biClrUsed == 0 ){
long x, y, xmin, xmax, ymin, ymax;
xmin = ymin = 0;
xmax = head.biWidth;
ymax = head.biHeight;
for( y = ymin; y < ymax; y++ ){
info.nProgress = (long)(50*y/ymax);
if (info.nEscape) break;
for( x = xmin; x < xmax; x++ ){
color = GetPixelColor( x, y );
tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if ( tmpGray < lowerc ) lowerc = tmpGray;
if ( tmpGray > upperd ) upperd = tmpGray;
}
}
if (upperd==lowerc) return false;
for( y = ymin; y < ymax; y++ ){
info.nProgress = (long)(50+50*y/ymax);
if (info.nEscape) break;
for( x = xmin; x < xmax; x++ ){
color = GetPixelColor( x, y );
yuvClr = RGBtoYUV(color);
// Stretch Luminance
tmpGray = (double)yuvClr.rgbRed;
stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
if ( stretcheds < 0.0 ) stretcheds = 0.0;
else if ( stretcheds > 255.0 ) stretcheds = 255.0;
yuvClr.rgbRed = (BYTE)stretcheds;
color = YUVtoRGB(yuvClr);
SetPixelColor( x, y, color );
}
}
} else {
DWORD j;
for( j = 0; j < head.biClrUsed; j++ ){
color = GetPaletteColor( (BYTE)j );
tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if ( tmpGray < lowerc ) lowerc = tmpGray;
if ( tmpGray > upperd ) upperd = tmpGray;
}
if (upperd==lowerc) return false;
for( j = 0; j < head.biClrUsed; j++ ){
color = GetPaletteColor( (BYTE)j );
yuvClr = RGBtoYUV( color );
// Stretch Luminance
tmpGray = (double)yuvClr.rgbRed;
stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
if ( stretcheds < 0.0 ) stretcheds = 0.0;
else if ( stretcheds > 255.0 ) stretcheds = 255.0;
yuvClr.rgbRed = (BYTE)stretcheds;
color = YUVtoRGB(yuvClr);
SetPaletteColor( (BYTE)j, color );
}
}
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramEqualize()
{
if (!pDib) return false;
int histogram[256];
int map[256];
int equalize_map[256];
int x, y, i, j;
RGBQUAD color;
RGBQUAD yuvClr;
unsigned int YVal, high, low;
memset( &histogram, 0, sizeof(int) * 256 );
memset( &map, 0, sizeof(int) * 256 );
memset( &equalize_map, 0, sizeof(int) * 256 );
// form histogram
for(y=0; y < head.biHeight; y++){
info.nProgress = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = GetPixelColor( x, y );
YVal = (unsigned int)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] = (unsigned int)((((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 = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = GetPixelColor( x, y );
yuvClr = RGBtoYUV(color);
yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];
color = YUVtoRGB(yuvClr);
SetPixelColor( x, y, color );
}
}
} else { // Palette
for( i = 0; i < (int)head.biClrUsed; i++ ){
color = GetPaletteColor((BYTE)i);
yuvClr = RGBtoYUV(color);
yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed];
color = YUVtoRGB(yuvClr);
SetPaletteColor( (BYTE)i, color );
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
bool CxImage::HistogramNormalize()
{
if (!pDib) return false;
int histogram[256];
int threshold_intensity, intense;
int x, y, i;
unsigned int normalize_map[256];
unsigned int high, low, YVal;
RGBQUAD color;
RGBQUAD yuvClr;
memset( &histogram, 0, sizeof( int ) * 256 );
memset( &normalize_map, 0, sizeof( unsigned int ) * 256 );
// form histogram
for(y=0; y < head.biHeight; y++){
info.nProgress = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = GetPixelColor( x, y );
YVal = (unsigned int)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 < (int) low ){
normalize_map[i] = 0;
} else {
if(i > (int) 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 = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = GetPixelColor( x, y );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];
color = YUVtoRGB( yuvClr );
SetPixelColor( x, y, color );
}
}
} else {
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor( (BYTE)i );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed];
color = YUVtoRGB( yuvClr );
SetPaletteColor( (BYTE)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)|);
int x, y, i;
RGBQUAD color;
RGBQUAD yuvClr;
unsigned int 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 = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = GetPixelColor( x, y );
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
} else { // Palette
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor((BYTE)i);
YVal = (unsigned int)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 = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = GetPixelColor( x, y );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
color = YUVtoRGB( yuvClr );
SetPixelColor( x, y, color );
}
}
} else {
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor( (BYTE)i );
yuvClr = RGBtoYUV( color );
yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
color = YUVtoRGB( yuvClr );
SetPaletteColor( (BYTE)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)|);
int x, y, i;
RGBQUAD color;
RGBQUAD yuvClr;
double dtmp;
unsigned int 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 = (long)(50*y/head.biHeight);
if (info.nEscape) break;
for(x=0; x < head.biWidth; x++){
color = GetPixelColor( x, y );
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
} else { // Palette
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor((BYTE)i);
YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if (YVal > high ) high = YVal;
}
}
// Root Operator
double k = 128.0 / ::log( 1.0 + (double)high );
if( head.biClrUsed == 0 ){
for( y = 0; y < head.biHeight; y++ ){
info.nProgress = (long)(50+50*y/head.biHeight);
if (info.nEscape) break;
for( x = 0; x < head.biWidth; x++ ){
color = GetPixelColor( 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 = (BYTE)dtmp;
color = YUVtoRGB( yuvClr );
SetPixelColor( x, y, color );
}
}
} else {
for(i = 0; i < (int)head.biClrUsed; i++){
color = GetPaletteColor( (BYTE)i );
yuvClr = RGBtoYUV( color );
dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
if ( dtmp > 255.0 ) dtmp = 255.0;
if ( dtmp < 0 ) dtmp = 0;
yuvClr.rgbRed = (BYTE)dtmp;
color = YUVtoRGB( yuvClr );
SetPaletteColor( (BYTE)i, color );
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif

View File

@ -1,299 +0,0 @@
/*
* File: ximaico.cpp
* Purpose: Platform Independent ICON Image Class Loader and Writer (MS version)
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximaico.h"
#if CXIMAGE_SUPPORT_ICO
////////////////////////////////////////////////////////////////////////////////
bool CxImageICO::Decode(CxFile *hFile)
{
if (hFile==NULL) return false;
DWORD off = hFile->Tell(); //<yuandi>
int page=info.nFrame; //internal icon structure indexes
// read the first part of the header
ICONHEADER icon_header;
hFile->Read(&icon_header,sizeof(ICONHEADER),1);
// 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));
int c;
for (c = 0; c < icon_header.idCount; c++)
hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);
if ((page>=0)&&(page<icon_header.idCount)){
// get the bit count for the colors in the icon <CoreyRLucier>
BITMAPINFOHEADER bih;
hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);
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];
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
BYTE* dst = info.pImage;
BYTE* buf=(BYTE*)malloc(4*head.biHeight*head.biWidth);
BYTE* src = buf;
hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
#if CXIMAGE_SUPPORT_ALPHA
if (!AlphaIsValid()) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
for (long y = 0; y < head.biHeight; y++) {
for(long 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
int maskwdt = ((head.biWidth+31) / 32) * 4; //line width of AND mask (always 1 Bpp)
int masksize = head.biHeight * maskwdt; //size of mask
BYTE *mask = (BYTE *)malloc(masksize);
if (hFile->Read(mask, masksize, 1)){
bool bGoodMask=false;
for (int im=0;im<masksize;im++){
if (mask[im]!=255){
bGoodMask=true;
break;
}
}
if (bGoodMask){
#if CXIMAGE_SUPPORT_ALPHA
bool bNeedAlpha = false;
if (!AlphaIsValid()){
AlphaCreate();
} else {
bNeedAlpha=true; //32bit icon
}
for (int y = 0; y < head.biHeight; y++) {
for (int 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
if (c==24){ //check if there is only one transparent color
RGBQUAD cc,ct;
long* pcc = (long*)&cc;
long* pct = (long*)&ct;
int nTransColors=0;
for (int y = 0; y < head.biHeight; y++){
for (int x = 0; x < head.biWidth; x++){
if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
cc = GetPixelColor(x,y,false);
if (nTransColors==0){
nTransColors++;
ct = cc;
} else {
if (*pct!=*pcc){
nTransColors++;
}
}
}
}
}
if (nTransColors==1){
SetTransColor(ct);
SetTransIndex(0);
#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
BYTE colorsUsed[256];
memset(colorsUsed, 0, sizeof(colorsUsed));
for (int y = 0; y < head.biHeight; y++){
for (int x = 0; x < head.biWidth; x++){
colorsUsed[GetPixelIndex(x,y)] = 1;
}
}
int iTransIdx = -1;
for (int x = 0; x < (int)head.biClrUsed; 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 (int y = 0; y < head.biHeight; y++){
for (int 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, 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;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageICO::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
//check format limits
if ((head.biWidth>255)||(head.biHeight>255)){
strcpy(info.szLastError,"Can't save this image as icon");
return false;
}
//prepare the palette struct
RGBQUAD* pal=GetPalette();
if (head.biBitCount<=8 && pal==NULL) return false;
int maskwdt=((head.biWidth+31)/32)*4; //mask line width
int masksize=head.biHeight * maskwdt; //size of mask
int bitcount=head.biBitCount;
int 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
ICONHEADER icon_header={0,1,1};
ICONDIRENTRY icon_list={(BYTE)head.biWidth,(BYTE)head.biHeight,(BYTE)head.biClrUsed ,0,0,(WORD)bitcount,
sizeof(BITMAPINFOHEADER)+head.biClrUsed*sizeof(RGBQUAD)+
imagesize+masksize,
sizeof(ICONHEADER)+sizeof(ICONDIRENTRY)};
BITMAPINFOHEADER bi={sizeof(BITMAPINFOHEADER),head.biWidth,2*head.biHeight,1,(WORD)bitcount,
0,imagesize,0,0,0,0};
hFile->Write(&icon_header,sizeof(ICONHEADER),1); //write the headers
hFile->Write(&icon_list,sizeof(ICONDIRENTRY),1);
hFile->Write(&bi,sizeof(BITMAPINFOHEADER),1);
if (pal) hFile->Write(pal,head.biClrUsed*sizeof(RGBQUAD),1); //write palette
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid() && head.biClrUsed==0){
BYTE* src = info.pImage;
BYTE* buf=(BYTE*)malloc(imagesize);
BYTE* dst = buf;
for (long y = 0; y < head.biHeight; y++) {
for(long 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
BYTE* mask=(BYTE*)calloc(masksize,1); //create empty AND/XOR masks
if (!mask) return false;
//prepare the variables to build the mask
BYTE* iDst;
int pos,i;
RGBQUAD c={0,0,0,0};
RGBQUAD ct = GetTransColor();
long* pc = (long*)&c;
long* pct= (long*)&ct;
bool bTransparent = info.nBkgndIndex != -1;
#if CXIMAGE_SUPPORT_ALPHA
bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
bool bAlphaIsValid = AlphaIsValid();
#endif
//build the mask
for (int y = 0; y < head.biHeight; y++) {
for (int x = 0; x < head.biWidth; x++) {
i=0;
#if CXIMAGE_SUPPORT_ALPHA
if (bAlphaIsValid && AlphaGet(x,y)==0) i=1;
if (bAlphaPaletteIsValid && GetPixelColor(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

View File

@ -1,52 +0,0 @@
/*
* 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 {
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
DWORD dwImageOffset;
} ICONDIRENTRY;
typedef struct tagIconDir {
WORD idReserved;
WORD idType;
WORD idCount;
} ICONHEADER;
public:
CxImageICO(): CxImage(CXIMAGE_FORMAT_ICO) {}
// 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

View File

@ -1,388 +0,0 @@
// ximainfo.cpp : main attributes
/* 03/10/2004 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
/**
* \return the color used for transparency, and/or for background color
*/
RGBQUAD CxImage::GetTransColor()
{
if (head.biBitCount<24 && info.nBkgndIndex != -1) return GetPaletteColor((BYTE)info.nBkgndIndex);
return info.nBkgndColor;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the index used for transparency. Returns -1 for no transparancy.
*/
long 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(long idx)
{
info.nBkgndIndex = idx;
}
////////////////////////////////////////////////////////////////////////////////
/**
* 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
*/
BYTE CxImage::GetColorType()
{
BYTE b = (BYTE)((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.
*/
long CxImage::GetXDPI() const
{
return info.xDPI;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return Resolution for TIFF, JPEG, PNG and BMP formats.
*/
long CxImage::GetYDPI() const
{
return info.yDPI;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Set resolution for TIFF, JPEG, PNG and BMP formats.
*/
void CxImage::SetXDPI(long dpi)
{
if (dpi<=0) dpi=96;
info.xDPI = dpi;
head.biXPelsPerMeter = (long) floor(dpi * 10000.0 / 254.0 + 0.5);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Set resolution for TIFF, JPEG, PNG and BMP formats.
*/
void CxImage::SetYDPI(long dpi)
{
if (dpi<=0) dpi=96;
info.yDPI = dpi;
head.biYPelsPerMeter = (long) floor(dpi * 10000.0 / 254.0 + 0.5);
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetFlags
*/
DWORD 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(DWORD flags, bool bLockReservedFlags)
{
if (bLockReservedFlags) info.dwFlags = flags & 0x0000ffff;
else info.dwFlags = flags;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetCodecOption
*/
DWORD CxImage::GetCodecOption(DWORD imagetype)
{
if (imagetype<CMAX_IMAGE_FORMATS){
if (imagetype==0){
imagetype = GetType();
}
return info.dwCodecOpt[imagetype];
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Encode option for GIF, TIF and JPG.
* - 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, ...)
*
* \return true if everything is ok
*/
bool CxImage::SetCodecOption(DWORD opt, DWORD imagetype)
{
if (imagetype<CMAX_IMAGE_FORMATS){
if (imagetype==0){
imagetype = GetType();
}
info.dwCodecOpt[imagetype] = opt;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return internal hDib object..
*/
void* CxImage::GetDIB() const
{
return pDib;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetHeight() const
{
return head.biHeight;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CxImage::GetWidth() const
{
return head.biWidth;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return DWORD aligned width of the image.
*/
DWORD CxImage::GetEffWidth() const
{
return info.dwEffWidth;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return 2, 16, 256; 0 for RGB images.
*/
DWORD CxImage::GetNumColors() const
{
return head.biClrUsed;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return: 1, 4, 8, 24.
*/
WORD CxImage::GetBpp() const
{
return head.biBitCount;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return original image format
* \sa ENUM_CXIMAGE_FORMATS.
*/
DWORD CxImage::GetType() const
{
return info.dwType;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return current frame delay in milliseconds. Only for GIF and MNG formats.
*/
DWORD CxImage::GetFrameDelay() const
{
return info.dwFrameDelay;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets current frame delay. Only for GIF format.
* \param d = delay in milliseconds
*/
void CxImage::SetFrameDelay(DWORD d)
{
info.dwFrameDelay=d;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::GetOffset(long *x,long *y)
{
*x=info.xOffset;
*y=info.yOffset;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetOffset(long x,long y)
{
info.xOffset=x;
info.yOffset=y;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetJpegQuality
*/
BYTE CxImage::GetJpegQuality() const
{
return info.nQuality;
}
////////////////////////////////////////////////////////////////////////////////
/**
* quality level for JPEG and JPEG2000
* \param q: can be from 0 to 100
*/
void CxImage::SetJpegQuality(BYTE q){
info.nQuality = q;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \sa SetJpegScale
*/
BYTE CxImage::GetJpegScale() const
{
return info.nJpegScale;
}
////////////////////////////////////////////////////////////////////////////////
/**
* scaling down during JPEG decoding valid numbers are 1, 2, 4, 8
* \author [ignacio]
*/
void CxImage::SetJpegScale(BYTE q){
info.nJpegScale = q;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Used to monitor the slow loops.
* \return value is from 0 to 100.
* \sa SetProgress
*/
long CxImage::GetProgress() const
{
return info.nProgress;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return the escape code.
* \sa SetEscape
*/
long 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(long 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(long 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.
*/
long CxImage::GetNumFrames() const
{
return info.nNumFrames;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return the current selected image (zero-based index).
*/
long CxImage::GetFrame() const
{
return info.nFrame;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the image number that the next Decode() / Load() call will load
*/
void CxImage::SetFrame(long nFrame){
info.nFrame=nFrame;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the last reported error.
*/
const char* CxImage::GetLastError()
{
return info.szLastError;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return A.BBCCCDDDD
* - A = main version
* - BB = main revision
* - CCC = minor revision (letter)
* - DDDD = experimental revision
*/
const float CxImage::GetVersionNumber()
{
return 5.99003f;
}
////////////////////////////////////////////////////////////////////////////////
const TCHAR* CxImage::GetVersion()
{
static const TCHAR CxImageVersion[] = _T("CxImage 5.99c");
return (CxImageVersion);
}
////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -1,252 +0,0 @@
/*
* 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 long 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:
int Itx, Ity; // Counters
int Stepx, Stepy;
BYTE* IterImage; // Image pointer
CxImage *ima;
public:
// Constructors
CImageIterator ( void );
CImageIterator ( CxImage *image );
operator CxImage* ();
// Iterators
BOOL ItOK ();
void Reset ();
void Upset ();
void SetRow(BYTE *buf, int n);
void GetRow(BYTE *buf, int n);
BYTE GetByte( ) { return IterImage[Itx]; }
void SetByte(BYTE b) { IterImage[Itx] = b; }
BYTE* GetRow(void);
BYTE* GetRow(int n);
BOOL NextRow();
BOOL PrevRow();
BOOL NextByte();
BOOL PrevByte();
void SetSteps(int x, int y=0) { Stepx = x; Stepy = y; }
void GetSteps(int *x, int *y) { *x = Stepx; *y = Stepy; }
BOOL NextStep();
BOOL PrevStep();
void SetY(int y); /* AD - for interlace */
int GetY() {return Ity;}
BOOL GetCol(BYTE* pCol, DWORD x);
BOOL SetCol(BYTE* pCol, DWORD 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 >= (int)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(int y)
{
if ((y < 0) || (y > (int)ima->GetHeight())) return;
Ity = y;
IterImage = ima->GetBits() + ima->GetEffWidth()*y;
}
/////////////////////////////////////////////////////////////////////
inline void CImageIterator::SetRow(BYTE *buf, int n)
{
if (n<0) n = (int)ima->GetEffWidth();
else n = min(n,(int)ima->GetEffWidth());
if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(IterImage,buf,n);
}
/////////////////////////////////////////////////////////////////////
inline void CImageIterator::GetRow(BYTE *buf, int n)
{
if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(buf,IterImage,n);
}
/////////////////////////////////////////////////////////////////////
inline BYTE* CImageIterator::GetRow()
{
return IterImage;
}
/////////////////////////////////////////////////////////////////////
inline BYTE* CImageIterator::GetRow(int n)
{
SetY(n);
return IterImage;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::NextByte()
{
if (++Itx < (int)ima->GetEffWidth()) return 1;
else
if (++Ity < (int)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 < (int)ima->GetEffWidth()) return 1;
else {
Ity += Stepy;
if (Ity < (int)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 < (int)ima->GetHeight()) {
IterImage -= ima->GetEffWidth();
Itx = 0;
return 1;
} else
return 0;
}
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::GetCol(BYTE* pCol, DWORD x)
{
if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
return 0;
DWORD h = ima->GetHeight();
//DWORD line = ima->GetEffWidth();
BYTE bytes = ima->GetBpp()>>3;
BYTE* pSrc;
for (DWORD y=0;y<h;y++){
pSrc = ima->GetBits(y) + x*bytes;
for (BYTE w=0;w<bytes;w++){
*pCol++=*pSrc++;
}
}
return 1;
}
/////////////////////////////////////////////////////////////////////
inline BOOL CImageIterator::SetCol(BYTE* pCol, DWORD x)
{
if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
return 0;
DWORD h = ima->GetHeight();
//DWORD line = ima->GetEffWidth();
BYTE bytes = ima->GetBpp()>>3;
BYTE* pSrc;
for (DWORD y=0;y<h;y++){
pSrc = ima->GetBits(y) + x*bytes;
for (BYTE w=0;w<bytes;w++){
*pSrc++=*pCol++;
}
}
return 1;
}
/////////////////////////////////////////////////////////////////////
#endif

View File

@ -1,250 +0,0 @@
/*
* File: ximaj2k.cpp
* Purpose: Platform Independent J2K Image Class Loader and Writer
* 12/Jul/2002 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximaj2k.h"
#if CXIMAGE_SUPPORT_J2K
#define CEILDIV(a,b) ((a+b-1)/b)
////////////////////////////////////////////////////////////////////////////////
bool CxImageJ2K::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
try
{
BYTE* src;
long len;
j2k_image_t *img=NULL;
j2k_cp_t *cp=NULL;
long i,x,y,w,h,max;
len=hFile->Size();
src=(BYTE*)malloc(len);
hFile->Read(src, len, 1);
if (!j2k_decode(src, len, &img, &cp)) {
free(src);
throw "failed to decode J2K image!";
}
free(src);
if (img->numcomps==3 &&
img->comps[0].dx==img->comps[1].dx &&
img->comps[1].dx==img->comps[2].dx &&
img->comps[0].dy==img->comps[1].dy &&
img->comps[1].dy==img->comps[2].dy &&
img->comps[0].prec==img->comps[1].prec &&
img->comps[1].prec==img->comps[2].prec)
{
w=CEILDIV(img->x1-img->x0, img->comps[0].dx);
h=CEILDIV(img->y1-img->y0, img->comps[0].dy);
max=(1<<img->comps[0].prec)-1;
Create(w,h,24,CXIMAGE_FORMAT_J2K);
RGBQUAD c;
for (i=0,y=0; y<h; y++) {
for (x=0; x<w; x++,i++){
c.rgbRed = img->comps[0].data[i];
c.rgbGreen = img->comps[1].data[i];
c.rgbBlue = img->comps[2].data[i];
SetPixelColor(x,h-1-y,c);
}
}
} else {
int compno;
info.nNumFrames = img->numcomps;
if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){
j2k_destroy(&img,&cp);
throw "wrong frame!";
}
for (compno=0; compno<=info.nFrame; compno++) {
w=CEILDIV(img->x1-img->x0, img->comps[compno].dx);
h=CEILDIV(img->y1-img->y0, img->comps[compno].dy);
max=(1<<img->comps[compno].prec)-1;
Create(w,h,8,CXIMAGE_FORMAT_J2K);
SetGrayPalette();
for (i=0,y=0; y<h; y++) {
for (x=0; x<w; x++,i++){
SetPixelIndex(x,h-1-y,img->comps[compno].data[i]);
}
}
}
}
j2k_destroy(&img,&cp);
} catch (char *message) {
strncpy(info.szLastError,message,255);
return FALSE;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageJ2K::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
if (head.biClrUsed!=0 && !IsGrayScale()){
strcpy(info.szLastError,"J2K can save only RGB or GrayScale images");
return false;
}
int i,x,y;
j2k_image_t *img;
j2k_cp_t *cp;
j2k_tcp_t *tcp;
j2k_tccp_t *tccp;
img = (j2k_image_t *)calloc(sizeof(j2k_image_t),1);
cp = (j2k_cp_t *)calloc(sizeof(j2k_cp_t),1);
cp->tx0=0; cp->ty0=0;
cp->tw=1; cp->th=1;
cp->tcps=(j2k_tcp_t*)calloc(sizeof(j2k_tcp_t),1);
tcp=&cp->tcps[0];
long w=head.biWidth;
long h=head.biHeight;
tcp->numlayers=1;
for (i=0;i<tcp->numlayers;i++) tcp->rates[i]=(w*h*GetJpegQuality())/600;
if (IsGrayScale()) {
img->x0=0;
img->y0=0;
img->x1=w;
img->y1=h;
img->numcomps=1;
img->comps=(j2k_comp_t*)calloc(sizeof(j2k_comp_t),1);
img->comps[0].data=(int*)calloc(w*h*sizeof(int),1);
img->comps[0].prec=8;
img->comps[0].sgnd=0;
img->comps[0].dx=1;
img->comps[0].dy=1;
for (i=0,y=0; y<h; y++) {
for (x=0; x<w; x++,i++){
img->comps[0].data[i]=GetPixelIndex(x,h-1-y);
}
}
} else if (!IsIndexed()) {
img->x0=0;
img->y0=0;
img->x1=w;
img->y1=h;
img->numcomps=3;
img->comps=(j2k_comp_t*)calloc(img->numcomps*sizeof(j2k_comp_t),1);
for (i=0; i<img->numcomps; i++) {
img->comps[i].data=(int*)calloc(w*h*sizeof(int),1);
img->comps[i].prec=8;
img->comps[i].sgnd=0;
img->comps[i].dx=1;
img->comps[i].dy=1;
}
RGBQUAD c;
for (i=0,y=0; y<h; y++) {
for (x=0; x<w; x++,i++){
c=GetPixelColor(x,h-1-y);
img->comps[0].data[i]=c.rgbRed;
img->comps[1].data[i]=c.rgbGreen;
img->comps[2].data[i]=c.rgbBlue;
}
}
} else {
return 0;
}
cp->tdx=img->x1-img->x0;
cp->tdy=img->y1-img->y0;
tcp->csty=0;
tcp->prg=0;
tcp->mct=img->numcomps==3?1:0;
tcp->tccps=(j2k_tccp_t*)calloc(img->numcomps*sizeof(j2k_tccp_t),1);
int ir=0; /* or 1 ???*/
for (i=0; i<img->numcomps; i++) {
tccp=&tcp->tccps[i];
tccp->csty=0;
tccp->numresolutions=6;
tccp->cblkw=6;
tccp->cblkh=6;
tccp->cblksty=0;
tccp->qmfbid=ir?0:1;
tccp->qntsty=ir?J2K_CCP_QNTSTY_SEQNT:J2K_CCP_QNTSTY_NOQNT;
tccp->numgbits=2;
tccp->roishift=0;
j2k_calc_explicit_stepsizes(tccp, img->comps[i].prec);
}
BYTE* dest=(BYTE*)calloc(tcp->rates[tcp->numlayers-1]+2,1);
long len = j2k_encode(img, cp, dest, tcp->rates[tcp->numlayers-1]+2);
if (len==0) {
strcpy(info.szLastError,"J2K failed to encode image");
} else {
hFile->Write(dest, len, 1);
}
free(dest);
j2k_destroy(&img,&cp);
return (len!=0);
}
////////////////////////////////////////////////////////////////////////////////
static const double dwt_norms_97[4][10]={
{1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
{2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
{2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
};
////////////////////////////////////////////////////////////////////////////////
void CxImageJ2K::j2k_calc_explicit_stepsizes(j2k_tccp_t *tccp, int prec) {
int numbands, bandno;
numbands=3*tccp->numresolutions-2;
for (bandno=0; bandno<numbands; bandno++) {
double stepsize;
int resno, level, orient, gain;
resno=bandno==0?0:(bandno-1)/3+1;
orient=bandno==0?0:(bandno-1)%3+1;
level=tccp->numresolutions-1-resno;
gain=tccp->qmfbid==0?0:(orient==0?0:(orient==1||orient==2?1:2));
if (tccp->qntsty==J2K_CCP_QNTSTY_NOQNT) {
stepsize=1.0;
} else {
double norm=dwt_norms_97[orient][level];
stepsize=(1<<(gain+1))/norm;
}
j2k_encode_stepsize((int)floor(stepsize*8192.0), prec+gain, &tccp->stepsizes[bandno].expn, &tccp->stepsizes[bandno].mant);
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImageJ2K::j2k_encode_stepsize(int stepsize, int numbps, int *expn, int *mant) {
int p, n;
p=j2k_floorlog2(stepsize)-13;
n=11-j2k_floorlog2(stepsize);
*mant=(n<0?stepsize>>-n:stepsize<<n)&0x7ff;
*expn=numbps-p;
}
////////////////////////////////////////////////////////////////////////////////
int CxImageJ2K::j2k_floorlog2(int a) {
int l;
for (l=0; a>1; l++) {
a>>=1;
}
return l;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_J2K

View File

@ -1,46 +0,0 @@
/*
* File: ximaj2k.h
* Purpose: J2K Image Class Loader and Writer
*/
/* ==========================================================
* CxImageJ2K (c) 04/Aug/2002 Davide Pizzolato - www.xdp.it
* For conditions of distribution and use, see copyright notice in ximage.h
*
* based on LIBJ2K Copyright (c) 2001-2002, David Janssens - All rights reserved.
* ==========================================================
*/
#if !defined(__ximaJ2K_h)
#define __ximaJ2K_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_J2K
#define LIBJ2K_EXPORTS
extern "C" {
#include "../j2k/j2k.h"
};
class CxImageJ2K: public CxImage
{
public:
CxImageJ2K(): CxImage(CXIMAGE_FORMAT_J2K) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_J2K);}
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_J2K);}
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:
void j2k_calc_explicit_stepsizes(j2k_tccp_t *tccp, int prec);
void j2k_encode_stepsize(int stepsize, int numbps, int *expn, int *mant);
int j2k_floorlog2(int a);
};
#endif
#endif

View File

@ -1,265 +0,0 @@
/*
* File: ximajas.cpp
* Purpose: Platform Independent JasPer Image Class Loader and Writer
* 12/Apr/2003 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximajas.h"
#if CXIMAGE_SUPPORT_JASPER
////////////////////////////////////////////////////////////////////////////////
bool CxImageJAS::Decode(CxFile *hFile, DWORD imagetype)
{
if (hFile == NULL) return false;
jas_image_t *image=0;
jas_stream_t *in=0;
jas_matrix_t **bufs=0;
long i,error=0;
//jas_setdbglevel(0);
try
{
if (jas_init())
throw "cannot initialize jasper";
if (!(in = jas_stream_fdopen(0, "rb")))
throw "error: cannot open standard input";
CxFileJas src(hFile,in);
if (!(image = jas_image_decode(in, -1, 0)))
throw "error: cannot load image data";
long 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 (image->numcmpts_ > 64 || image->numcmpts_ < 0)
throw "error: too much components";
if (depth!=1 && depth!=4 && depth!=8){
jas_image_t *newimage;
jas_cmprof_t *outprof;
//jas_eprintf("forcing conversion to sRGB\n");
if (!(outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) {
throw "cannot create sRGB profile";
}
if (!(newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER))) {
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) {
if (!(bufs[i] = jas_matrix_create(1, w))) {
throw "error: cannot allocate memory";
}
}
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,imagetype))
throw "Can't allocate memory";
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 = (jas_matrix_getv(bufs[0], x));
c.rgbGreen = (jas_matrix_getv(bufs[1], x));
c.rgbBlue = (jas_matrix_getv(bufs[2], x));
SetPixelColor(x,h-1-y,c);
}
}
} else {
info.nNumFrames = image->numcmpts_;
if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){
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))
throw "Can't allocate memory";
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,(jas_matrix_getv(bufs[0], x)));
}
}
}
}
} catch (char *message) {
strncpy(info.szLastError,message,255);
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);
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageJAS::Encode(CxFile * hFile, DWORD 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];
long x,y,yflip,error=0;
uint_fast16_t cmptno, numcmpts;
jas_image_cmptparm_t cmptparms[3], *cmptparm;
try
{
if (jas_init())
throw "cannot initialize jasper";
if (!(out = jas_stream_fdopen(0, "wb")))
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. */
if (!(image = jas_image_create(numcmpts, cmptparms, JAS_CLRSPC_UNKNOWN)))
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) {
if (!(cmpts[x] = jas_matrix_create(1, head.biWidth))) {
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])) {
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) throw "PGX can save only GrayScale images";
}
#endif
int outfmt = jas_image_strtofmt(szfmt);
char szoutopts[16];
sprintf(szoutopts,"rate=%.3f", info.nQuality/100.0f);
if (jas_image_encode(image, out, outfmt, szoutopts)) {
throw "error: cannot encode image\n";
}
jas_stream_flush(out);
} catch (char *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

View File

@ -1,84 +0,0 @@
/*
* 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
#include "../jasper/include/jasper/jasper.h"
class CxImageJAS: public CxImage
{
public:
CxImageJAS(): CxImage((DWORD)0) {} // <vho> cast to DWORD
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,0);}
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,0);}
bool Decode(CxFile * hFile, DWORD imagetype = 0);
bool Decode(FILE *hFile, DWORD imagetype = 0) { CxIOFile file(hFile); return Decode(&file,imagetype); }
#if CXIMAGE_SUPPORT_ENCODE
bool Encode(CxFile * hFile, DWORD imagetype = 0);
bool Encode(FILE *hFile, DWORD 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 int JasRead(jas_stream_obj_t *obj, char *buf, int cnt)
{ return ((CxFile*)obj)->Read(buf,1,cnt); }
static int JasWrite(jas_stream_obj_t *obj, char *buf, int cnt)
{ return ((CxFile*)obj)->Write(buf,1,cnt); }
static long JasSeek(jas_stream_obj_t *obj, long offset, int origin)
{ return ((CxFile*)obj)->Seek(offset,origin); }
static int JasClose(jas_stream_obj_t *obj)
{ return 1; }
// <vho>
private:
jas_stream_ops_t jas_stream_CxFile;
// <vho> - end
};
};
#endif
#endif

View File

@ -1,162 +0,0 @@
/*
* File: ximajbg.cpp
* Purpose: Platform Independent JBG Image Class Loader and Writer
* 18/Aug/2002 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximajbg.h"
#if CXIMAGE_SUPPORT_JBG
#include "ximaiter.h"
#define JBIG_BUFSIZE 8192
////////////////////////////////////////////////////////////////////////////////
bool CxImageJBG::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
struct jbg_dec_state jbig_state;
unsigned long xmax = 4294967295UL, ymax = 4294967295UL;
unsigned int len, cnt;
BYTE *buffer,*p;
int result;
try
{
jbg_dec_init(&jbig_state);
jbg_dec_maxsize(&jbig_state, xmax, ymax);
buffer = (BYTE*)malloc(JBIG_BUFSIZE);
if (!buffer) 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())
throw "Problem while reading input file";
if (result != JBG_EOK && result != JBG_EOK_INTR)
throw "Problem with input file";
int 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;
switch (planes){
case 1:
{
BYTE* binary_image = jbg_dec_getimage(&jbig_state, 0);
if (!Create(w,h,1,CXIMAGE_FORMAT_JBG))
throw "Can't allocate memory";
SetPaletteColor(0,255,255,255);
SetPaletteColor(1,0,0,0);
CImageIterator iter(this);
iter.Upset();
for (int i=0;i<h;i++){
iter.SetRow(binary_image+i*ew,ew);
iter.PrevRow();
}
break;
}
default:
throw "cannot decode images with more than 1 plane";
}
jbg_dec_free(&jbig_state);
free(buffer);
} catch (char *message) {
jbg_dec_free(&jbig_state);
if (buffer) free(buffer);
strncpy(info.szLastError,message,255);
return FALSE;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
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;
}
int 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;
BYTE mask;
RGBQUAD *rgb = GetPalette();
if (CompareColors(&rgb[0],&rgb[1])<0) mask=255; else mask=0;
BYTE *buffer = (BYTE*)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)
int dl = -1, dh = -1, d = -1, l0 = -1, mx = -1;
int options = JBG_TPDON | JBG_TPBON | JBG_DPON;
int 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

View File

@ -1,44 +0,0 @@
/*
* 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 char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JBG);}
// bool Save(const char * 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(BYTE *buffer, unsigned int len, void *file)
{((CxFile*)file)->Write(buffer,len,1);}
};
#endif
#endif

View File

@ -1,454 +0,0 @@
/*
* File: ximajpg.cpp
* Purpose: Platform Independent JPEG Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximajpg.h"
#if CXIMAGE_SUPPORT_JPG
#include "../jpeg/jmorecfg.h"
#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(&m_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(&m_exifinfo);
if (m_exif){
long pos=hFile->Tell();
m_exif->DecodeExif(hFile);
hFile->Seek(pos,SEEK_SET);
return m_exif->m_exifinfo->IsExif;
} else {
return false;
}
}
#endif //CXIMAGEJPG_SUPPORT_EXIF
////////////////////////////////////////////////////////////////////////////////
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 */
int 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;
/* 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);
CxFileJpg src(hFile);
cinfo.src = &src;
/* Step 3: read file parameters with jpeg_read_header() */
(void) jpeg_read_header(&cinfo, TRUE);
/* Step 4 <chupeev> handle decoder options*/
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_GRAYSCALE) != 0)
cinfo.out_color_space = JCS_GRAYSCALE;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_QUANTIZE) != 0) {
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = info.nQuality;
}
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_DITHER) != 0)
cinfo.dither_mode = m_nDither;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & DECODE_ONEPASS) != 0)
cinfo.two_pass_quantize = FALSE;
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & 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>
// 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;
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 ((m_exifinfo.Xresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0))
SetXDPI((long)(m_exifinfo.Xresolution/m_exifinfo.ResolutionUnit));
if ((m_exifinfo.Yresolution != 0.0) && (m_exifinfo.ResolutionUnit != 0))
SetYDPI((long)(m_exifinfo.Yresolution/m_exifinfo.ResolutionUnit));
#endif
} else {
if (cinfo.density_unit==2){
SetXDPI((long)floor(cinfo.X_density * 254.0 / 10000.0 + 0.5));
SetYDPI((long)floor(cinfo.Y_density * 254.0 / 10000.0 + 0.5));
} else {
SetXDPI(cinfo.X_density);
SetYDPI(cinfo.Y_density);
}
}
if (cinfo.out_color_space==JCS_GRAYSCALE){
SetGrayPalette();
head.biClrUsed =256;
} else {
if (cinfo.quantize_colors==TRUE){
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 = (long)(100*cinfo.output_scanline/cinfo.output_height);
//<DP> Step 6a: CMYK->RGB */
if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
BYTE k,*dst,*src;
dst=iter.GetRow();
src=buffer[0];
for(long x3=0,x4=0; x3<(long)info.dwEffWidth && x4<row_stride; x3+=3, x4+=4){
k=src[x4+3];
dst[x3] =(BYTE)((k * src[x4+2])/255);
dst[x3+1]=(BYTE)((k * src[x4+1])/255);
dst[x3+2]=(BYTE)((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)){
BYTE* r0=GetBits();
for(long 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;
}
////////////////////////////////////////////////////////////////////////////////
#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
long 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 long 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 */
int 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:
*/
//#ifdef C_ARITH_CODING_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_ARITHMETIC) != 0)
cinfo.arith_code = TRUE;
//#endif
//#ifdef ENTROPY_OPT_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_OPTIMIZE) != 0)
cinfo.optimize_coding = TRUE;
//#endif
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_GRAYSCALE) != 0)
jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_SMOOTHING) != 0)
cinfo.smoothing_factor = m_nSmoothing;
jpeg_set_quality(&cinfo, GetJpegQuality(), (GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_BASELINE) != 0);
//#ifdef C_PROGRESSIVE_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_PROGRESSIVE) != 0)
jpeg_simple_progression(&cinfo);
//#endif
#ifdef C_LOSSLESS_SUPPORTED
if ((GetCodecOption(CXIMAGE_FORMAT_JPG) & ENCODE_LOSSLESS) != 0)
jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform);
#endif
cinfo.density_unit=1;
cinfo.X_density=(unsigned short)GetXDPI();
cinfo.Y_density=(unsigned short)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 = (long)(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

View File

@ -1,315 +0,0 @@
/*
* 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 __ixmaJPEG_h
#include "ximage.h"
#if CXIMAGE_SUPPORT_JPG
#define CXIMAGEJPG_SUPPORT_EXIF 1
extern "C" {
#include "../jpeg/jpeglib.h"
#include "../jpeg/jerror.h"
}
class DLL_EXP CxImageJPG: public CxImage
{
public:
CxImageJPG();
~CxImageJPG();
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);}
// bool Save(const char * 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
#define MAX_COMMENT 1000
#define MAX_SECTIONS 20
typedef struct tag_ExifInfo {
char Version [5];
char CameraMake [32];
char CameraModel [40];
char DateTime [20];
int Height, Width;
int Orientation;
int IsColor;
int Process;
int FlashUsed;
float FocalLength;
float ExposureTime;
float ApertureFNumber;
float Distance;
float CCDWidth;
float ExposureBias;
int Whitebalance;
int MeteringMode;
int ExposureProgram;
int ISOequivalent;
int CompressionLevel;
float FocalplaneXRes;
float FocalplaneYRes;
float FocalplaneUnits;
float Xresolution;
float Yresolution;
float ResolutionUnit;
float Brightness;
char Comments[MAX_COMMENT];
unsigned char * ThumbnailPointer; /* Pointer at the thumbnail */
unsigned ThumbnailSize; /* Size of thumbnail. */
bool IsExif;
} EXIFINFO;
//--------------------------------------------------------------------------
// 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{
BYTE* Data;
int Type;
unsigned Size;
} Section_t;
public:
EXIFINFO* m_exifinfo;
char m_szLastError[256];
CxExifInfo(EXIFINFO* info = NULL);
~CxExifInfo();
bool DecodeExif(CxFile * hFile, int nReadMode = EXIF_READ_EXIF);
bool EncodeExif(CxFile * hFile);
void DiscardAllButExif();
protected:
bool process_EXIF(unsigned char * CharBuf, unsigned int length);
void process_COM (const BYTE * Data, int length);
void process_SOFn (const BYTE * Data, int marker);
int Get16u(void * Short);
int Get16m(void * Short);
long Get32s(void * Long);
unsigned long Get32u(void * Long);
double ConvertAnyFormat(void * ValuePtr, int Format);
void* FindSection(int SectionType);
bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
EXIFINFO * const pInfo, unsigned char ** const LastExifRefdP);
int ExifImageWidth;
int MotorolaOrder;
Section_t Sections[MAX_SECTIONS];
int SectionsRead;
bool freeinfo;
};
CxExifInfo* m_exif;
EXIFINFO m_exifinfo;
bool DecodeExif(CxFile * hFile);
bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); }
#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 unsigned char[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 > (long)pSource->bytes_in_buffer){
num_bytes -= (long)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;
unsigned char *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
};
int m_nPredictor;
int m_nPointTransform;
int m_nSmoothing;
int m_nQuantize;
J_DITHER_MODE m_nDither;
};
#endif
#endif

View File

@ -1,321 +0,0 @@
// xImalpha.cpp : Alpha channel functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_ALPHA
////////////////////////////////////////////////////////////////////////////////
/**
* \sa AlphaSetMax
*/
BYTE 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(BYTE 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;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Inverts the alpha channel.
*/
void CxImage::AlphaClear()
{
if (pAlpha) memset(pAlpha,0,head.biWidth * head.biHeight);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the alpha level for the whole image
*/
void CxImage::AlphaSet(BYTE level)
{
if (pAlpha) memset(pAlpha,level,head.biWidth * head.biHeight);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Allocates an empty (opaque) alpha channel.
*/
void CxImage::AlphaCreate()
{
if (pAlpha==NULL) {
pAlpha = (BYTE*)malloc(head.biWidth * head.biHeight);
if (pAlpha) memset(pAlpha,255,head.biWidth * head.biHeight);
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::AlphaDelete()
{
if (pAlpha) { free(pAlpha); pAlpha=0; }
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::AlphaInvert()
{
if (pAlpha) {
BYTE *iSrc=pAlpha;
long n=head.biHeight*head.biWidth;
for(long i=0; i < n; i++){
*iSrc=(BYTE)~(*(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 = (BYTE*)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 = (BYTE*)malloc(head.biWidth * head.biHeight);
BYTE* src = from.info.pImage;
BYTE* dst = pAlpha;
if (src==NULL || dst==NULL) return false;
for (long 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 long x,const long y,const BYTE level)
{
if (pAlpha && IsInside(x,y)) pAlpha[x+y*head.biWidth]=level;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the alpha level for a single pixel
*/
BYTE CxImage::AlphaGet(const long x,const long 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
*/
BYTE* CxImage::AlphaGetPointer(const long x,const long 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
*/
BYTE CxImage::BlindAlphaGet(const long x,const long y)
{
#ifdef _DEBUG
if (!IsInside(x,y) || (pAlpha==0)) throw 0;
#endif
return pAlpha[x+y*head.biWidth];
}
////////////////////////////////////////////////////////////////////////////////
/**
* Resets the alpha palette
*/
void CxImage::AlphaPaletteClear()
{
RGBQUAD c;
for(WORD ip=0; ip<head.biClrUsed;ip++){
c=GetPaletteColor((BYTE)ip);
c.rgbReserved=0;
SetPaletteColor((BYTE)ip,c);
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image has a valid alpha palette.
*/
bool CxImage::AlphaPaletteIsValid()
{
RGBQUAD c;
for(WORD ip=0; ip<head.biClrUsed;ip++){
c=GetPaletteColor((BYTE)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;
long a, a1;
if (head.biBitCount==24){
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
c=GetPixelColor(x,y);
if (bAlphaIsValid) a=(AlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
a1 = 255-a;
c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)/255);
c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)/255);
c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)/255);
SetPixelColor(x,y,c);
}
}
AlphaDelete();
} else {
CxImage tmp(head.biWidth,head.biHeight,24);
if (!tmp.IsValid()) return;
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
c=GetPixelColor(x,y);
if (bAlphaIsValid) a=(AlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
if (bAlphaPaletteIsValid) a=(c.rgbReserved*a)/255;
a1 = 255-a;
c.rgbBlue = (BYTE)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)/255);
c.rgbGreen = (BYTE)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)/255);
c.rgbRed = (BYTE)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)/255);
tmp.SetPixelColor(x,y,c);
}
}
Transfer(tmp);
}
return;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::AlphaFlip()
{
if (!pAlpha) return false;
BYTE* pAlpha2 = (BYTE*)malloc(head.biWidth * head.biHeight);
if (!pAlpha2) return false;
BYTE *iSrc,*iDst;
iSrc=pAlpha + (head.biHeight-1)*head.biWidth;
iDst=pAlpha2;
for(long y=0; y < head.biHeight; y++){
memcpy(iDst,iSrc,head.biWidth);
iSrc-=head.biWidth;
iDst+=head.biWidth;
}
free(pAlpha);
pAlpha=pAlpha2;
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::AlphaMirror()
{
if (!pAlpha) return false;
BYTE* pAlpha2 = (BYTE*)malloc(head.biWidth * head.biHeight);
if (!pAlpha2) return false;
BYTE *iSrc,*iDst;
long wdt=head.biWidth-1;
iSrc=pAlpha + wdt;
iDst=pAlpha2;
for(long y=0; y < head.biHeight; y++){
for(long 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()) return false;
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.SetPixelIndex(x,y,pAlpha[x+y*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()) return false;
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.SetPixelIndex(x,y,GetPixelColor(x,y).rgbReserved);
}
}
tmp.SetGrayPalette();
dest->Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_ALPHA

View File

@ -1,105 +0,0 @@
// xImaLyr.cpp : Layers functions
/* 21/04/2003 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#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.
*/
long 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(long position)
{
if ( position < 0 || position > info.nNumLayers ) position = info.nNumLayers;
CxImage** ptmp = (CxImage**)malloc((info.nNumLayers + 1)*sizeof(CxImage**));
if (ptmp==0) return false;
int i=0;
for (int n=0; n<info.nNumLayers; n++){
if (position == n){
ptmp[n] = new CxImage();
i=1;
}
ptmp[n+i]=pLayers[n];
}
if (i==0) ptmp[info.nNumLayers] = new CxImage();
if (ptmp[position]){
ptmp[position]->info.pParent = this;
} else {
free(ptmp);
return false;
}
info.nNumLayers++;
if (pLayers) free(pLayers);
pLayers = ptmp;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Deletes a layer. If position is less than 0, the last layer will be deleted
*/
bool CxImage::LayerDelete(long position)
{
if ( position >= info.nNumLayers ) return false;
if ( position < 0) position = info.nNumLayers - 1;
CxImage** ptmp = (CxImage**)malloc((info.nNumLayers - 1)*sizeof(CxImage**));
if (ptmp==0) return false;
int i=0;
for (int n=0; n<(info.nNumLayers - 1); n++){
if (position == n){
delete pLayers[n];
i=1;
}
ptmp[n]=pLayers[n+i];
}
if (i==0) delete pLayers[info.nNumLayers - 1];
info.nNumLayers--;
if (pLayers) free(pLayers);
pLayers = ptmp;
return true;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::LayerDeleteAll()
{
if (pLayers) {
for(long n=0; n<info.nNumLayers;n++){ delete pLayers[n]; }
free(pLayers); pLayers=0;
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns a pointer to a layer. If position is less than 0, the last layer will be returned
*/
CxImage* CxImage::GetLayer(long position)
{
if ( position >= info.nNumLayers ) return 0;
if ( position < 0) position = info.nNumLayers - 1;
return pLayers[position];
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_LAYERS

View File

@ -1,366 +0,0 @@
/*
* File: ximamng.cpp
* Purpose: Platform Independent MNG Image Class Loader and Writer
* Author: 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximamng.h"
#if CXIMAGE_SUPPORT_MNG
////////////////////////////////////////////////////////////////////////////////
// callbacks for the mng decoder:
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// memory allocation; data must be zeroed
static mng_ptr
mymngalloc( mng_uint32 size )
{
return (mng_ptr)calloc(1, size);
}
////////////////////////////////////////////////////////////////////////////////
// memory deallocation
static void mymngfree(mng_ptr p, mng_uint32 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(BYTE), 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 = (BYTE*)malloc(height * mymng->effwdt);
// tell the mng decoder about our bit-depth choice
mng_set_canvasstyle( mng, MNG_CANVAS_BGR8 );
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)));
}
////////////////////////////////////////////////////////////////////////////////
// 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)
{
//throw (const char *)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 (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);
}
////////////////////////////////////////////////////////////////////////////////
// can't use the CxImage implementation because it looses mnginfo
bool CxImageMNG::Load(const char * imageFileName){
FILE* hFile; //file handle to read the image
if ((hFile=fopen(imageFileName,"rb"))==NULL) return false;
bool bOK = Decode(hFile);
fclose(hFile);
return bOK;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageMNG::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
try {
// set up the mng decoder for our stream
hmng = mng_initialize(&mnginfo, mymngalloc, mymngfree, MNG_NULL);
if (hmng == NULL) 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:
WORD 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;
mng_readdisplay(hmng);
// read all
int retval=MNG_NOERROR;
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 (int n=0;n<info.nFrame;n++) mng_display_resume(hmng);
} else throw "Error: frame not present in MNG file";
}
if (mnginfo.nBkgndIndex != -1){
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, mnginfo.effwdt * mnginfo.height);
} else throw "CxImageMNG::Decode cannot create image";
} catch (char *message) {
strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageMNG::Encode(CxFile *hFile)
{
if (EncodeSafeCheck(hFile)) return false;
try {
if (head.biClrUsed != 0) 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 = (BYTE*)malloc(head.biSizeImage);
if (mnginfo.image == NULL) 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, mymngalloc, mymngfree, MNG_NULL);
if (hmng == NULL) 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);
} catch (char *message) {
strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// Writes a single PNG datastream
void CxImageMNG::WritePNG( mng_handle hMNG, int Frame, int FrameCount )
{
mngstuff *mymng = (mngstuff *)mng_get_userdata(hMNG);
int OffsetX=0,OffsetY=0,OffsetW=mymng->width,OffsetH=mymng->height;
BYTE *tmpbuffer = new BYTE[ (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( int 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):
BYTE *dstbuffer = new BYTE[(mymng->effwdt+1)*OffsetH];
if( dstbuffer == 0 ) return;
DWORD 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;
}
////////////////////////////////////////////////////////////////////////////////
long 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, mnginfo.effwdt * mnginfo.height);
} 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_MNG

View File

@ -1,86 +0,0 @@
/*
* 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"
}
//unsigned long _stdcall RunMNGThread(void *lpParam);
typedef struct tagmngstuff
{
CxFile *file;
BYTE *image;
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;
long nBkgndIndex;
RGBQUAD nBkgndColor;
} mngstuff;
class CxImageMNG: public CxImage
{
public:
CxImageMNG();
~CxImageMNG();
bool Load(const char * imageFileName);
bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_MNG);}
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
long Resume();
void SetSpeed(float speed);
mng_handle hmng;
mngstuff mnginfo;
protected:
void WritePNG(mng_handle hMNG, int Frame, int FrameCount );
void SetCallbacks(mng_handle mng);
};
#endif
#endif

View File

@ -1,707 +0,0 @@
// xImaPal.cpp : Palette and Pixel functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
////////////////////////////////////////////////////////////////////////////////
/**
* returns the palette dimension in byte
*/
DWORD CxImage::GetPaletteSize()
{
return (head.biClrUsed * sizeof(RGBQUAD));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) b;
iDst[ldx++] = (BYTE) g;
iDst[ldx++] = (BYTE) r;
iDst[ldx] = (BYTE) alpha;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, RGBQUAD c)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) c.rgbBlue;
iDst[ldx++] = (BYTE) c.rgbGreen;
iDst[ldx++] = (BYTE) c.rgbRed;
iDst[ldx] = (BYTE) c.rgbReserved;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPaletteColor(BYTE idx, COLORREF cr)
{
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
iDst[ldx++] = (BYTE) GetBValue(cr);
iDst[ldx++] = (BYTE) GetGValue(cr);
iDst[ldx++] = (BYTE) GetRValue(cr);
iDst[ldx] = (BYTE) 0;
info.last_c_isvalid = false;
}
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* returns the pointer to the first palette index
*/
RGBQUAD* CxImage::GetPalette() const
{
if ((pDib)&&(head.biClrUsed))
return (RGBQUAD*)((BYTE*)pDib + sizeof(BITMAPINFOHEADER));
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the color of the specified index.
*/
RGBQUAD CxImage::GetPaletteColor(BYTE idx)
{
RGBQUAD rgb = {0,0,0,0};
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long 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.
*/
BYTE CxImage::GetPixelIndex(long x,long y)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
if ((x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) {
if (info.nBkgndIndex != -1) return (BYTE)info.nBkgndIndex;
else return *info.pImage;
}
if (head.biBitCount==8){
return info.pImage[y*info.dwEffWidth + x];
} else {
BYTE pos;
BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
iDst &= (0x0F<<pos);
return (BYTE)(iDst >> pos);
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
iDst &= (0x01<<pos);
return (BYTE)(iDst >> pos);
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::BlindGetPixelIndex(const long x,const long y)
{
#ifdef _DEBUG
if ((pDib==NULL) || (head.biClrUsed==0) || !IsInside(x,y)) throw 0;
#endif
if (head.biBitCount==8){
return info.pImage[y*info.dwEffWidth + x];
} else {
BYTE pos;
BYTE iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
iDst &= (0x0F<<pos);
return (BYTE)(iDst >> pos);
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
iDst &= (0x01<<pos);
return (BYTE)(iDst >> pos);
}
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
RGBQUAD CxImage::GetPixelColor(long x,long 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 != -1){
if (head.biBitCount<24) return GetPaletteColor((BYTE)info.nBkgndIndex);
else return info.nBkgndColor;
} else if (pDib) return GetPixelColor(0,0);
return rgb;
}
if (head.biClrUsed){
rgb = GetPaletteColor(GetPixelIndex(x,y));
} else {
BYTE* 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 = AlphaGet(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 long x,const long y)
{
RGBQUAD rgb;
#ifdef _DEBUG
if ((pDib==NULL) || !IsInside(x,y)) throw 0;
#endif
if (head.biClrUsed){
return GetPaletteColor(BlindGetPixelIndex(x,y));
}
BYTE* iDst = info.pImage + y*info.dwEffWidth + x*3;
rgb.rgbBlue = *iDst++;
rgb.rgbGreen= *iDst++;
rgb.rgbRed = *iDst;
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha) rgb.rgbReserved = pAlpha[x+y*head.biWidth];
#else
rgb.rgbReserved = 0;
#endif //CXIMAGE_SUPPORT_ALPHA
return rgb;
}
////////////////////////////////////////////////////////////////////////////////
BYTE CxImage::GetPixelGray(long x, long y)
{
RGBQUAD color = GetPixelColor(x,y);
return (BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelIndex(long x,long y,BYTE 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 {
BYTE pos;
BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
*iDst &= ~(0x0F<<pos);
*iDst |= ((i & 0x0F)<<pos);
return;
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
*iDst &= ~(0x01<<pos);
*iDst |= ((i & 0x01)<<pos);
return;
}
}
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelColor(long x,long y,COLORREF cr)
{
SetPixelColor(x,y,RGBtoRGBQUAD(cr));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha)
{
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)) return;
if (head.biClrUsed)
SetPixelIndex(x,y,GetNearestIndex(c));
else {
BYTE* 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(long x,long y,RGBQUAD c, float blend, bool bSetAlpha)
{
if ((pDib==NULL)||(x<0)||(y<0)||
(x>=head.biWidth)||(y>=head.biHeight)) return;
int a0 = (int)(256*blend);
int a1 = 256 - a0;
RGBQUAD c0 = BlindGetPixelColor(x,y);
c.rgbRed = (BYTE)((c.rgbRed * a0 + c0.rgbRed * a1)>>8);
c.rgbBlue = (BYTE)((c.rgbBlue * a0 + c0.rgbBlue * a1)>>8);
c.rgbGreen = (BYTE)((c.rgbGreen * a0 + c0.rgbGreen * a1)>>8);
if (head.biClrUsed)
SetPixelIndex(x,y,GetNearestIndex(c));
else {
BYTE* 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.
*/
BYTE CxImage::GetNearestIndex(RGBQUAD c)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
// <RJ> check matching with the previous result
if (info.last_c_isvalid && (*(long*)&info.last_c == *(long*)&c)) return info.last_c_index;
info.last_c = c;
info.last_c_isvalid = true;
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
long distance=200000;
int i,j = 0;
long k,l;
int m = (int)(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 = j;
return (BYTE)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(BYTE *buffer, int length)
{
if (buffer && (head.biClrUsed==0)){
BYTE temp;
length = min(length,(int)info.dwEffWidth);
for (int 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 DWORD */
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(BYTE i, BYTE* r, BYTE* g, BYTE* 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(DWORD n, BYTE *r, BYTE *g, BYTE *b)
{
if ((!r)||(pDib==NULL)||(head.biClrUsed==0)) return;
if (!g) g = r;
if (!b) b = g;
RGBQUAD* ppal=GetPalette();
DWORD m=min(n,head.biClrUsed);
for (DWORD 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,DWORD nColors)
{
if ((!rgb)||(pDib==NULL)||(head.biClrUsed==0)) return;
RGBQUAD* ppal=GetPalette();
DWORD m=min(nColors,head.biClrUsed);
for (DWORD 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,DWORD 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 (DWORD ni=0;ni<head.biClrUsed;ni++)
pal[ni].rgbBlue=pal[ni].rgbGreen = pal[ni].rgbRed = (BYTE)(ni*(255/(head.biClrUsed-1)));
}
////////////////////////////////////////////////////////////////////////////////
/**
* Colorize the palette.
* \sa Colorize
*/
void CxImage::BlendPalette(COLORREF cr,long perc)
{
if ((pDib==NULL)||(head.biClrUsed==0)) return;
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
DWORD 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=(BYTE)((pPal[i].rgbBlue*(100-perc)+b*perc)/100);
pPal[i].rgbGreen =(BYTE)((pPal[i].rgbGreen*(100-perc)+g*perc)/100);
pPal[i].rgbRed =(BYTE)((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(DWORD 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(BYTE idx1, BYTE 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
BYTE idx;
for(long y=0; y < head.biHeight; y++){
for(long x=0; x <= head.biWidth; x++){
idx=GetPixelIndex(x,y);
if (idx==idx1) SetPixelIndex(x,y,idx2);
if (idx==idx2) SetPixelIndex(x,y,idx1);
}
}
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::IsTransparent(long x, long 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 (*(long*)&c==*(long*)&ct) return true;
}
}
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha) return AlphaGet(x,y)==0;
#endif
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* 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 (DWORD n=0; n<head.biClrUsed; n++){
c1 = GetPaletteColor((BYTE)n);
c2 = img.GetPaletteColor((BYTE)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
*/
DWORD 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(DWORD 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 long x, const long y)
{
if (!IsIndexed())
return info.pImage + y*info.dwEffWidth + x*3;
else
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr)
{
DrawLine(StartX, EndX, StartY, EndY, RGBtoRGBQUAD(cr));
}
////////////////////////////////////////////////////////////////////////////////
void CxImage::DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha)
{
if (!pDib) return;
//////////////////////////////////////////////////////
// Draws a line using the Bresenham line algorithm
// Thanks to Jordan DeLozier <JDL>
//////////////////////////////////////////////////////
int x1 = StartX;
int y1 = StartY;
int x = x1; // Start x off at the first pixel
int y = y1; // Start y off at the first pixel
int x2 = EndX;
int y2 = EndY;
int xinc1,xinc2,yinc1,yinc2; // Increasing values
int den, num, numadd,numpixels;
int deltax = abs(x2 - x1); // The difference between the x's
int 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 (int 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 4 and 8 bpp images.
*/
void CxImage::SetStdPalette()
{
if (!pDib) return;
switch (head.biBitCount){
case 8:
{
const BYTE 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 BYTE 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;
}
}
return;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,445 +0,0 @@
/*
* File: ximapcx.cpp
* Purpose: Platform Independent PCX Image Class Loader and Writer
* 05/Jan/2002 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*
* 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
////////////////////////////////////////////////////////////////////////////////
bool CxImagePCX::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
PCXHEADER pcxHeader;
int i, x, y, y2, nbytes, count, Height, Width;
BYTE c, ColorMap[PCX_MAXCOLORS][3];
BYTE *pcximage = NULL, *lpHead1 = NULL, *lpHead2 = NULL;
BYTE *pcxplanes, *pcxpixels;
try
{
if (hFile->Read(&pcxHeader,sizeof(PCXHEADER),1)==0) throw "Can't read PCX image";
if (pcxHeader.Manufacturer != PCX_MAGIC) throw "Error: Not a PCX file";
// Check for PCX run length encoding
if (pcxHeader.Encoding != 1) 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;
// Check that we can handle this image format
if (pcxHeader.ColorPlanes > 4)
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) throw "Cancelled"; // <vho> - cancel decoding
//Read the image and check if it's ok
nbytes = pcxHeader.BytesPerLine * pcxHeader.ColorPlanes * Height;
lpHead1 = pcximage = (BYTE*)malloc(nbytes);
while (nbytes > 0){
if (hFile == NULL || hFile->Eof()) 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) 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) 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 (DWORD idx=0; idx<head.biClrUsed; idx++) SetPaletteColor((BYTE)idx,ColorMap[idx][0],ColorMap[idx][1],ColorMap[idx][2]);
lpHead2 = pcxpixels = (BYTE *)malloc(Width + pcxHeader.BytesPerLine * 8);
// Convert the image
for (y = 0; y < Height; y++){
if (info.nEscape) 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) {
PCX_UnpackPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel);
} else {
PCX_PlanesToPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel);
}
for (x = 0; x < Width; x++) SetPixelIndex(x,y2,pcxpixels[x]);
}
} catch (char *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;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImagePCX::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
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 = (WORD)head.biWidth-1;
pcxHeader.Ymax = (WORD)head.biHeight-1;
pcxHeader.Hres = (WORD)info.xDPI;
pcxHeader.Vres = (WORD)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 = (WORD)head.biWidth;
break;
}
default: //(4 1)
pcxHeader.BitsPerPixel = 1;
pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1;
pcxHeader.BytesPerLine = (WORD)((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 (int 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);
if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 )
throw "cannot write PCX header";
CxMemFile buffer;
buffer.Open();
BYTE c,n;
long x,y;
if (head.biClrUsed==0){
for (y = head.biHeight-1; y >=0 ; y--){
for (int p=0; p<pcxHeader.ColorPlanes; p++){
c=n=0;
for (x = 0; x<head.biWidth; x++){
if (p==0)
PCX_PackPixels(GetPixelColor(x,y).rgbRed,c,n,buffer);
else if (p==1)
PCX_PackPixels(GetPixelColor(x,y).rgbGreen,c,n,buffer);
else if (p==2)
PCX_PackPixels(GetPixelColor(x,y).rgbBlue,c,n,buffer);
#if CXIMAGE_SUPPORT_ALPHA
else if (p==3)
PCX_PackPixels(AlphaGet(x,y),c,n,buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
}
PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
}
}
hFile->Write(buffer.GetBuffer(false),buffer.Size(),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.Size(),1);
if (head.biBitCount == 8){
hFile->PutC(0x0C);
BYTE* pal = (BYTE*)malloc(768);
RGBQUAD c;
for (int 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);
BYTE* plane = (BYTE*)malloc(pcxHeader.BytesPerLine);
BYTE* raw = (BYTE*)malloc(head.biWidth);
for(y = head.biHeight-1; y >=0 ; y--) {
for( x = 0; x < head.biWidth; x++) raw[x] = (BYTE)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.Size(),1);
}
} catch (char *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
void CxImagePCX::PCX_PlanesToPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel)
{
int i, j, npixels;
BYTE * p;
if (planes > 4) throw "Can't handle more than 4 planes";
if (bitsperpixel != 1) throw "Can't handle more than 1 bit per pixel";
// 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++){
int 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;
}
}
}
////////////////////////////////////////////////////////////////////////////////
// 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
void CxImagePCX::PCX_UnpackPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel)
{
register int bits;
if (planes != 1) throw "Can't handle packed pixels with more than 1 plane.";
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++ = (BYTE)((bits >> 4) & 0X0F);
*pixels++ = (BYTE)((bits) & 0X0F);
}
} else if (bitsperpixel == 2){ // 2 bits/pixel, four pixels per byte
while (bytesperline-- > 0){
bits = *bitplanes++;
*pixels++ = (BYTE)((bits >> 6) & 0X03);
*pixels++ = (BYTE)((bits >> 4) & 0X03);
*pixels++ = (BYTE)((bits >> 2) & 0X03);
*pixels++ = (BYTE)((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);
}
}
}
////////////////////////////////////////////////////////////////////////////////
/* PCX_PackPixels(const long p,BYTE &c, BYTE &n, long &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 long p,BYTE &c, BYTE &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=(BYTE)p;
n++;
}
////////////////////////////////////////////////////////////////////////////////
void CxImagePCX::PCX_PackPlanes(BYTE* buff, const long size, CxFile &f)
{
BYTE *start,*end;
BYTE 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(BYTE* raw, long width, BYTE* buf, long plane)
{
int cbit, x, mask;
unsigned char *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;
}
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_PCX

View File

@ -1,63 +0,0 @@
/*
* 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
WORD Xmin, Ymin; // image origin
WORD Xmax, Ymax; // image dimensions
WORD Hres, Vres; // resolution values
BYTE ColorMap[16][3]; // color palette
char Reserved;
char ColorPlanes; // color planes
WORD BytesPerLine; // line buffer size
WORD PaletteType; // grey or color palette
char Filter[58];
} PCXHEADER;
#pragma pack()
public:
CxImagePCX(): CxImage(CXIMAGE_FORMAT_PCX) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PCX);}
// bool Save(const char * 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:
void PCX_PlanesToPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel);
void PCX_UnpackPixels(BYTE * pixels, BYTE * bitplanes, short bytesperline, short planes, short bitsperpixel);
void PCX_PackPixels(const long p,BYTE &c, BYTE &n, CxFile &f);
void PCX_PackPlanes(BYTE* buff, const long size, CxFile &f);
void PCX_PixelsToPlanes(BYTE* raw, long width, BYTE* buf, long plane);
};
#endif
#endif

View File

@ -1,507 +0,0 @@
/*
* File: ximapng.cpp
* Purpose: Platform Independent PNG Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#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->jmpbuf, 1);
}
////////////////////////////////////////////////////////////////////////////////
void CxImagePNG::expand2to4bpp(BYTE* prow)
{
BYTE *psrc,*pdst;
BYTE pos,idx;
for(long x=head.biWidth-1;x>=0;x--){
psrc = prow + ((2*x)>>3);
pdst = prow + ((4*x)>>3);
pos = (BYTE)(2*(3-x%4));
idx = (BYTE)((*psrc & (0x03<<pos))>>pos);
pos = (BYTE)(4*(1-x%2));
*pdst &= ~(0x0F<<pos);
*pdst |= (idx & 0x0F)<<pos;
}
}
////////////////////////////////////////////////////////////////////////////////
bool CxImagePNG::Decode(CxFile *hFile)
{
int number_passes;
png_struct *png_ptr;
png_info *info_ptr;
BYTE *row_pointers=NULL;
CImageIterator iter(this);
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) 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);
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->jmpbuf)) {
/* Free all of the memory associated with the png_ptr and info_ptr */
if (row_pointers) delete[] row_pointers;
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
throw "";
}
/* set up the input control */
//png_init_io(png_ptr, hFile);
// 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);
/* allocate the memory to hold the image using the fields of png_info. */
png_color_16 my_background={ 0, 192, 192, 192, 0 };
png_color_16 *image_background;
if (info_ptr->pixel_depth != 32){
//<yeonjun jeong> preserve original background info.
if (png_get_bKGD(png_ptr, info_ptr, &image_background))
png_set_background(png_ptr, image_background,PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else
png_set_background(png_ptr, &my_background,PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
// <vho> - we call png_set_bgr() below
// <vho> //<yeonjun jeong> safe check
// <vho> if (info_ptr->pixel_depth > 16 ) info_ptr->color_type = COLORTYPE_COLOR;
}
//<DP> hack for images with alpha channel
if (info_ptr->pixel_depth == 32){
// info.nBkgndIndex = 0; //enable transparency
if (png_get_bKGD(png_ptr, info_ptr, &image_background)){
info.nBkgndColor.rgbRed = (BYTE)image_background->red;
info.nBkgndColor.rgbGreen = (BYTE)image_background->green;
info.nBkgndColor.rgbBlue = (BYTE)image_background->blue;
info.nBkgndColor.rgbReserved = 0; // <vho>
}
}
/* tell libpng to strip 16 bit depth files down to 8 bits */
if (info_ptr->bit_depth == 16) png_set_strip_16(png_ptr);
int pixel_depth=info_ptr->pixel_depth;
if (pixel_depth > 16 ) pixel_depth=24;
if (pixel_depth == 16 ) pixel_depth=8;
Create(info_ptr->width, info_ptr->height, pixel_depth, CXIMAGE_FORMAT_PNG);
/* 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((long)floor(info_ptr->x_pixels_per_unit * 254.0 / 10000.0 + 0.5));
SetYDPI((long)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);
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
// simple transparency (the real PGN transparency is more complex)
if (info_ptr->num_trans!=0){
//palette transparency
RGBQUAD* pal=GetPalette();
if (pal){
DWORD ip;
for (ip=0;ip<min(head.biClrUsed,(unsigned long)info_ptr->num_trans);ip++)
pal[ip].rgbReserved=info_ptr->trans[ip];
if (info_ptr->num_trans==1 && pal[0].rgbReserved==0){
info.nBkgndIndex = 0;
} else {
info.bAlphaPaletteEnabled=true;
for (;ip<head.biClrUsed;ip++)
pal[ip].rgbReserved=255;
}
}
}
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || //Alpha channel
(info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && info_ptr->pixel_depth == 32)){
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA){
png_set_gray_to_rgb(png_ptr);
png_set_expand(png_ptr);
}
#if CXIMAGE_SUPPORT_ALPHA // <vho>
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
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->jmpbuf, 1);
//allocate the buffer
int row_stride = info_ptr->width * ((info_ptr->pixel_depth+7)>>3);
row_pointers = new BYTE[10+row_stride];
// turn on interlace handling
number_passes = png_set_interlace_handling(png_ptr);
if (number_passes>1){
SetCodecOption(1);
} else {
SetCodecOption(0);
}
for (int pass=0; pass< number_passes; pass++) {
iter.Upset();
int y=0;
do {
// <vho> - handle cancel
if (info.nEscape) longjmp(png_ptr->jmpbuf, 1);
#if CXIMAGE_SUPPORT_ALPHA // <vho>
if (!AlphaIsValid())
#endif // CXIMAGE_SUPPORT_ALPHA
{
//recover data from previous scan
if (info_ptr->interlace_type && pass>0)
iter.GetRow(row_pointers, info.dwEffWidth);
//read next row
png_read_row(png_ptr, row_pointers, NULL);
// <vho> - already done by png_set_bgr()
// <vho> //HACK BY OP && (<DP> for interlace, swap only in the last pass)
// <vho> if (info_ptr->color_type==COLORTYPE_COLOR && pass==(number_passes-1))
// <vho> RGBtoBGR(row_pointers, info.dwEffWidth);
//<DP> expand 2 bpp images only in the last pass
if (info_ptr->bit_depth==2 && pass==(number_passes-1))
expand2to4bpp(row_pointers);
//copy the pixels
iter.SetRow(row_pointers, info.dwEffWidth);
//go on
iter.PrevRow();
}
#if CXIMAGE_SUPPORT_ALPHA // <vho>
else { //alpha blend
//compute the correct position of the line
long ax,ay;
ay = head.biHeight-1-y;
BYTE* prow= iter.GetRow(ay);
//recover data from previous scan
if (info_ptr->interlace_type && pass>0 && pass!=7){
for(ax=head.biWidth;ax>=0;ax--){
row_pointers[ax*4]=prow[3*ax];
row_pointers[ax*4+1]=prow[3*ax+1];
row_pointers[ax*4+2]=prow[3*ax+2];
row_pointers[ax*4+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++){
prow[3*ax]=row_pointers[ax*4];
prow[3*ax+1]=row_pointers[ax*4+1];
prow[3*ax+2]=row_pointers[ax*4+2];
AlphaSet(ax,ay,row_pointers[ax*4+3]);
}
}
#endif // CXIMAGE_SUPPORT_ALPHA // vho
y++;
} while(y<head.biHeight);
}
delete[] row_pointers;
/* read the rest of the file, getting any additional chunks in info_ptr */
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);
} catch (char *message) {
if (strcmp(message,"")) strncpy(info.szLastError,message,255);
return FALSE;
}
/* that's it */
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImagePNG::Encode(CxFile *hFile)
{
if (EncodeSafeCheck(hFile)) return false;
CImageIterator iter(this);
BYTE trans[256]; //for transparency (don't move)
png_struct *png_ptr;
png_info *info_ptr;
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) 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);
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->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);
throw "Error saving PNG file";
}
int row_stride = info.dwEffWidth;
/* 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 = (BYTE)GetBpp();
info_ptr->channels = (GetBpp()>8) ? (BYTE)3: (BYTE)1;
info_ptr->bit_depth = (BYTE)(GetBpp()/info_ptr->channels);
info_ptr->color_type = GetColorType();
info_ptr->compression_type = info_ptr->filter_type = 0;
info_ptr->valid = 0;
info_ptr->rowbytes = row_stride;
switch(GetCodecOption(CXIMAGE_FORMAT_PNG)){
case 1:
info_ptr->interlace_type = PNG_INTERLACE_ADAM7;
break;
default:
info_ptr->interlace_type = PNG_INTERLACE_NONE;
}
/* set compression level */
//png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
/* set background */
png_color_16 image_background={ 0, 255, 255, 255, 0 };
if (info.nBkgndIndex!=-1) {
image_background.blue = info.nBkgndColor.rgbBlue;
image_background.green = info.nBkgndColor.rgbGreen;
image_background.red = info.nBkgndColor.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);
/* set the palette if there is one */
if (GetPalette()){
png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth,
PNG_COLOR_TYPE_PALETTE, info_ptr->interlace_type,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
info_ptr->valid |= PNG_INFO_PLTE;
//<DP> simple transparency
if (info.nBkgndIndex != -1){
trans[0]=0;
info_ptr->num_trans = 1;
info_ptr->valid |= PNG_INFO_tRNS;
info_ptr->trans = trans;
// the transparency indexes start from 0
if (info.nBkgndIndex){
SwapIndex(0,(BYTE)info.nBkgndIndex);
// the ghost must set the changed attributes in the body
if (info.pGhost) info.pGhost->SetTransIndex(0);
}
}
int nc = GetNumColors();
/* We not need to write unused colors! <Basara>*/
/* only for small images <DP>*/
if ((nc>2)&&((head.biWidth*head.biHeight)<65536)){
nc = 0;
for (DWORD y=0;y<GetHeight();y++){
for (DWORD x=0;x<GetWidth();x++){
if (GetPixelIndex(x,y)>nc){
nc=GetPixelIndex(x,y);
}
}
}
nc++;
}
if (info.bAlphaPaletteEnabled){
for(WORD ip=0; ip<nc;ip++)
trans[ip]=GetPaletteColor((BYTE)ip).rgbReserved;
info_ptr->num_trans = (WORD)nc;
info_ptr->valid |= PNG_INFO_tRNS;
info_ptr->trans = trans;
}
// copy the palette colors
info_ptr->palette = new png_color[nc];
info_ptr->num_palette = (png_uint_16) nc;
for (int 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
bool bNeedTempAlpha = false;
if (head.biBitCount==24 && info.nBkgndIndex>=0){
if (!AlphaIsValid()){
bNeedTempAlpha = true;
AlphaCreate();
}
RGBQUAD c,ct=GetTransColor();
for(long y=0; y < head.biHeight; y++){
for(long x=0; x < head.biWidth ; x++){
c=GetPixelColor(x,y,false);
if (*(long*)&c==*(long*)&ct)
AlphaSet(x,y,0);
}}
}
#endif // CXIMAGE_SUPPORT_ALPHA // <vho>
#if CXIMAGE_SUPPORT_ALPHA // <vho>
if (AlphaIsValid()){
row_stride = 4 * head.biWidth;
info_ptr->pixel_depth = 32;
info_ptr->channels = 4;
info_ptr->bit_depth = 8;
info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
info_ptr->rowbytes = row_stride;
/* write the file information */
png_write_info(png_ptr, info_ptr);
//<Ranger> "10+row_stride" fix heap deallocation problem during debug???
BYTE *row_pointers = new BYTE[10+row_stride];
//interlace handling
int num_pass = png_set_interlace_handling(png_ptr);
for (int pass = 0; pass < num_pass; pass++){
//write image
iter.Upset();
long ay=head.biHeight-1;
RGBQUAD c;
do {
for (long ax=head.biWidth-1; ax>=0;ax--){
c=GetPixelColor(ax,ay);
row_pointers[ax*4+3]=(BYTE)((AlphaGet(ax,ay)*info.nAlphaMax)/255);
row_pointers[ax*4+2]=c.rgbBlue;
row_pointers[ax*4+1]=c.rgbGreen;
row_pointers[ax*4]=c.rgbRed;
}
png_write_row(png_ptr, row_pointers);
ay--;
} while(iter.PrevRow());
}
delete [] row_pointers;
}
else
#endif //CXIMAGE_SUPPORT_ALPHA // <vho>
{
/* write the file information */
png_write_info(png_ptr, info_ptr);
/* If you are only writing one row at a time, this works */
BYTE *row_pointers = new BYTE[10+row_stride];
//interlace handling
int num_pass = png_set_interlace_handling(png_ptr);
for (int pass = 0; pass < num_pass; pass++){
//write image
iter.Upset();
do {
iter.GetRow(row_pointers, row_stride);
//HACK BY OP
if (info_ptr->color_type == 2 /*COLORTYPE_COLOR*/)
RGBtoBGR(row_pointers, row_stride);
png_write_row(png_ptr, row_pointers);
} while(iter.PrevRow());
}
delete [] row_pointers;
}
#if CXIMAGE_SUPPORT_ALPHA // <vho>
/* remove the temporary alpha channel*/
if (bNeedTempAlpha) AlphaDelete();
#endif // CXIMAGE_SUPPORT_ALPHA // <vho>
/* 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);
/* clean up after the write, and free any memory allocated */
png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
} catch (char *message) {
strncpy(info.szLastError,message,255);
return FALSE;
}
/* that's it */
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_PNG

View File

@ -1,73 +0,0 @@
/*
* 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" {
#include "../png/png.h"
}
class CxImagePNG: public CxImage
{
public:
CxImagePNG(): CxImage(CXIMAGE_FORMAT_PNG) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PNG);}
// bool Save(const char * 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
protected:
void ima_png_error(png_struct *png_ptr, char *message);
void expand2to4bpp(BYTE* prow);
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
CxFile* hFile = (CxFile*)png_ptr->io_ptr;
if (hFile->Read(data,1,length) != length) png_error(png_ptr, "Read Error");
}
static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
CxFile* hFile = (CxFile*)png_ptr->io_ptr;
if (hFile->Write(data,1,length) != length) png_error(png_ptr, "Write Error");
}
static void user_flush_data(png_structp png_ptr)
{
CxFile* hFile = (CxFile*)png_ptr->io_ptr;
if (!hFile->Flush()) png_error(png_ptr, "Flush Error");
}
static void user_error_fn(png_structp png_ptr,png_const_charp error_msg)
{
strncpy((char*)png_ptr->error_ptr,error_msg,255);
longjmp(png_ptr->jmpbuf, 1);
}
};
#endif
#endif

View File

@ -1,469 +0,0 @@
// xImaSel.cpp : Selection functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_SELECTION
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the image has a valid selection.
*/
bool CxImage::SelectionIsValid()
{
return pSelection!=0;
}
////////////////////////////////////////////////////////////////////////////////
/**
* 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()
{
if (pSelection){
memset(pSelection,0,head.biWidth * head.biHeight);
info.rSelectionBox.left = head.biWidth;
info.rSelectionBox.bottom = head.biHeight;
info.rSelectionBox.right = info.rSelectionBox.top = 0;
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Allocates an empty selection.
*/
bool CxImage::SelectionCreate()
{
SelectionDelete();
pSelection = (BYTE*)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(long x, long y)
{
if (IsInside(x,y)){
if (pSelection==NULL) return true;
return pSelection[x+y*head.biWidth]!=0;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds a rectangle to the existing selection.
*/
bool CxImage::SelectionAddRect(RECT r)
{
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));
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));
if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0L,min(head.biHeight,r2.bottom));
long ymin = max(0L,min(head.biHeight,r2.bottom));
long ymax = max(0L,min(head.biHeight,r2.top));
long xmin = max(0L,min(head.biWidth,r2.left));
long xmax = max(0L,min(head.biWidth,r2.right));
for (long y=ymin; y<ymax; y++)
memset(pSelection + xmin + y * head.biWidth, 255, xmax-xmin);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds an ellipse to the existing selection.
*/
bool CxImage::SelectionAddEllipse(RECT r)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
long xradius = abs(r.right - r.left)/2;
long yradius = abs(r.top - r.bottom)/2;
if (xradius==0 || yradius==0) return false;
long xcenter = (r.right + r.left)/2;
long 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)));
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)));
long xmin = max(0L,min(head.biWidth,xcenter - xradius));
long xmax = max(0L,min(head.biWidth,xcenter + xradius));
long ymin = max(0L,min(head.biHeight,ycenter - yradius));
long ymax = max(0L,min(head.biHeight,ycenter + yradius));
long y,yo;
for (y=ymin; y<ycenter; y++){
for (long x=xmin; x<xmax; x++){
yo = (long)(ycenter - yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
if (yo<y) pSelection[x + y * head.biWidth] = 255;
}
}
for (y=ycenter; y<ymax; y++){
for (long x=xmin; x<xmax; x++){
yo = (long)(ycenter + yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
if (yo>y) pSelection[x + y * head.biWidth] = 255;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Inverts the selection.
*/
bool CxImage::SelectionInvert()
{
if (pSelection) {
BYTE *iSrc=pSelection;
long n=head.biHeight*head.biWidth;
for(long i=0; i < n; i++){
*iSrc=(BYTE)~(*(iSrc));
iSrc++;
}
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 = (BYTE*)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, long npoints)
{
if (points==NULL || npoints<3) return false;
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
BYTE* plocal = (BYTE*)calloc(head.biWidth*head.biHeight, 1);
RECT localbox = {head.biWidth,0,0,head.biHeight};
long x,y,i=0;
POINT *current,*next,*start;
//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 = (long)(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 = (long)(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 = (long)(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 = (long)(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
long npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom);
POINT* pix = (POINT*)calloc(npix,sizeof(POINT));
BYTE back=0, mark=1;
long fx, fy, fxx, fyy, first, last,xmin,xmax,ymin,ymax;
for (int 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;
do {
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++;
} while(1);
fx = pix[first].x - 1;
fy = pix[first].y;
fxx = fx + x;
fyy = fy + y;
do {
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--;
} while(1);
first++;
if (first == npix) first = 0;
}
}
}
}
}
//transfer the region
long 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]=255;
}
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;
free(plocal);
free(pix);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds to the selection all the pixels matching the specified color.
*/
bool CxImage::SelectionAddColor(RGBQUAD c)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
RECT localbox = {head.biWidth,0,0,head.biHeight};
for (long y = 0; y < head.biHeight; y++){
for (long x = 0; x < head.biWidth; x++){
RGBQUAD color = GetPixelColor(x, y);
if (color.rgbRed == c.rgbRed &&
color.rgbGreen == c.rgbGreen &&
color.rgbBlue == c.rgbBlue)
{
pSelection[x + y * head.biWidth] = 255; // set the correct mask bit
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;
if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
if (info.rSelectionBox.right < localbox.right) info.rSelectionBox.right = localbox.right;
if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Adds a single pixel to the existing selection.
*/
bool CxImage::SelectionAddPixel(int x, int y)
{
if (pSelection==NULL) SelectionCreate();
if (pSelection==NULL) return false;
if (IsInside(x,y)) {
pSelection[x + y * head.biWidth] = 255; // set the correct mask bit
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()) return false;
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
tmp.SetPixelIndex(x,y,pSelection[x+y*head.biWidth]);
}
}
tmp.SetGrayPalette();
dest->Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_WINDOWS
/**
* Converts the selection in a HRGN object.
*/
bool CxImage::SelectionToHRGN(HRGN& region)
{
if (pSelection && region){
for(int y = 0; y < head.biHeight; y++){
HRGN hTemp = NULL;
int iStart = -1;
int x = 0;
for(; x < head.biWidth; x++){
if (pSelection[x + y * head.biWidth] == 255){
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

View File

@ -1,300 +0,0 @@
/*
* File: ximatga.cpp
* Purpose: Platform Independent TGA Image Class Loader and Writer
* 05/Jan/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#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
////////////////////////////////////////////////////////////////////////////////
bool CxImageTGA::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
TGAHEADER tgaHead;
try
{
if (hFile->Read(&tgaHead,sizeof(tgaHead),1)==0)
throw "Not a TGA";
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:
throw "Unknown TGA image type";
}
if (tgaHead.ImageWidth==0 || tgaHead.ImageHeight==0 || tgaHead.PixelDepth==0 || tgaHead.CmapLength>256)
throw "bad TGA header";
if (tgaHead.PixelDepth!=8 && tgaHead.PixelDepth!=15 && tgaHead.PixelDepth!=16 && tgaHead.PixelDepth!=24 && tgaHead.PixelDepth!=32)
throw "bad TGA header";
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()) throw "TGA Create failed";
if (info.nEscape) 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 (int i=0;i<tgaHead.CmapLength; i++) SetPaletteColor((BYTE)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);
BYTE rleLeftover = 255; //for images with illegal packet boundary
BYTE* pDest;
for (int y=0; y < tgaHead.ImageHeight; y++){
if (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding
if (hFile == NULL || hFile->Eof()) 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
} catch (char *message) {
strncpy(info.szLastError,message,255);
return FALSE;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#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) ? (BYTE)TGA_Map : (BYTE)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) ? (BYTE)24 : (BYTE)0; // Color Map Entry Size
tgaHead.X_Origin=0; // X-origin of Image
tgaHead.Y_Origin=0; // Y-origin of Image
tgaHead.ImageWidth=(WORD)head.biWidth; // Image Width
tgaHead.ImageHeight=(WORD)head.biHeight; // Image Height
tgaHead.PixelDepth=(BYTE)head.biBitCount; // Pixel Depth
tgaHead.ImagDesc=0; // Image Descriptor
if (pAlpha && head.biBitCount==24) tgaHead.PixelDepth=32;
hFile->Write(&tgaHead,sizeof(TGAHEADER),1);
if (head.biBitCount==8){
rgb_color pal[256];
RGBQUAD* ppal = GetPalette();
for (int 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);
BYTE* pDest;
if (pAlpha==0 || head.biBitCount==8){
for (int y=0; y < tgaHead.ImageHeight; y++){
pDest = iter.GetRow(y);
hFile->Write(pDest,tgaHead.ImageWidth * (head.biBitCount >> 3),1);
}
} else {
pDest = (BYTE*)malloc(4*tgaHead.ImageWidth);
RGBQUAD c;
for (int y=0; y < tgaHead.ImageHeight; y++){
for(int x=0, x4=0;x<tgaHead.ImageWidth;x++, x4+=4){
c=GetPixelColor(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]=(BYTE)((AlphaGet(x,y)*info.nAlphaMax)/255);
#else
pDest[x4+3]=0;
#endif //CXIMAGE_SUPPORT_ALPHA
}
hFile->Write(pDest,4*tgaHead.ImageWidth,1);
}
free(pDest);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
BYTE CxImageTGA::ExpandCompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, BYTE rleLeftover)
{
try{
BYTE rle;
long filePos;
for (int 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 = 128 + (rle - (width - x) - 1);
filePos = hFile->Tell();
rle=width-x;
}
switch (ptgaHead->PixelDepth)
{
case 32: {
RGBQUAD color;
hFile->Read(&color,4,1);
for (int 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 (int ix = 0; ix < rle; ix++) memcpy(&pDest[3*ix],&triple,3);
break;
}
case 15:
case 16: {
WORD pixel;
hFile->Read(&pixel,2,1);
rgb_color triple;
triple.r = (BYTE)(( pixel & 0x1F ) * 8); // red
triple.g = (BYTE)(( pixel >> 2 ) & 0x0F8); // green
triple.b = (BYTE)(( pixel >> 7 ) & 0x0F8); // blue
for (int ix = 0; ix < rle; ix++){
memcpy(&pDest[3*ix],&triple,3);
}
break;
}
case 8: {
BYTE pixel;
hFile->Read(&pixel,1,1);
for (int 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 = rle - (width - x) - 1;
rle=width-x;
}
ExpandUncompressedLine(pDest,ptgaHead,hFile,rle,y,x);
}
if (head.biBitCount == 24) pDest += rle*3; else pDest += rle;
x += rle;
}
} catch(...){ }
return rleLeftover;
}
////////////////////////////////////////////////////////////////////////////////
void CxImageTGA::ExpandUncompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, int xoffset)
{
try{
switch (ptgaHead->PixelDepth){
case 8:
hFile->Read(pDest,width,1);
break;
case 15:
case 16:{
BYTE* dst=pDest;
WORD pixel;
for (int x=0; x<width; x++){
hFile->Read(&pixel,2,1);
*dst++ = (BYTE)(( pixel & 0x1F ) * 8); // blue
*dst++ = (BYTE)(( pixel >> 2 ) & 0x0F8); // green
*dst++ = (BYTE)(( pixel >> 7 ) & 0x0F8); // red
}
break;
}
case 24:
hFile->Read(pDest,3*width,1);
break;
case 32:{
BYTE* dst=pDest;
for (int 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;
}
}
} catch(...){ }
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_TGA

View File

@ -1,60 +0,0 @@
/*
* 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
{
BYTE IdLength; // Image ID Field Length
BYTE CmapType; // Color Map Type
BYTE ImageType; // Image Type
WORD CmapIndex; // First Entry Index
WORD CmapLength; // Color Map Length
BYTE CmapEntrySize; // Color Map Entry Size
WORD X_Origin; // X-origin of Image
WORD Y_Origin; // Y-origin of Image
WORD ImageWidth; // Image Width
WORD ImageHeight; // Image Height
BYTE PixelDepth; // Pixel Depth
BYTE ImagDesc; // Image Descriptor
} TGAHEADER;
#pragma pack()
public:
CxImageTGA(): CxImage(CXIMAGE_FORMAT_TGA) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TGA);}
// bool Save(const char * 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:
BYTE ExpandCompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, BYTE rleLeftover);
void ExpandUncompressedLine(BYTE* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int width, int y, int xoffset);
};
#endif
#endif

View File

@ -1,97 +0,0 @@
#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;
}

View File

@ -1,39 +0,0 @@
#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

View File

@ -1,763 +0,0 @@
/*
* File: ximatif.cpp
* Purpose: Platform Independent TIFF Image Class Loader and Writer
* 07/Aug/2001 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximatif.h"
#if CXIMAGE_SUPPORT_TIF
#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);
}
////////////////////////////////////////////////////////////////////////////////
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=(DWORD)-1;
uint16 photometric=0;
uint16 compression=1;
uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
uint16 res_unit; //<Trifon>
uint32 x, y;
float resolution, offset;
BOOL isRGB;
BYTE *bits; //pointer to source data
BYTE *bits2; //pointer to destination data
try{
//check if it's a tiff file
if (!m_tif)
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))
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;
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((long)resolution);
}
if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
{
if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
SetYDPI((long)resolution);
}
if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset)) info.xOffset = (long)offset;
if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset)) info.yOffset = (long)offset;
head.biClrUsed=0;
info.nBkgndIndex =-1;
if (rowsperstrip>height){
rowsperstrip=height;
TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
}
isRGB = (bitspersample >= 8) &&
(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)){
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 (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding
Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF); //image creation
if (!pDib) 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) 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);
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);
throw "Cancelled";
}
bits = bits2;
for (x = 0; x < width; x++) {
*bits++ = (BYTE)TIFFGetB(row[x]);
*bits++ = (BYTE)TIFFGetG(row[x]);
*bits++ = (BYTE)TIFFGetR(row[x]);
#if CXIMAGE_SUPPORT_ALPHA
if (samplesperpixel==4) AlphaSet(x,y,(BYTE)TIFFGetA(row[x]));
#endif //CXIMAGE_SUPPORT_ALPHA
}
row += width;
bits2 += info.dwEffWidth;
}
_TIFFfree(raster);
} else {
RGBQUAD *pal;
pal=(RGBQUAD*)calloc(256,sizeof(RGBQUAD));
if (pal==NULL) throw "Unable to allocate TIFF palette";
// 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 (DWORD i=0; i<head.biClrUsed; i++){
pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(i*(255/(head.biClrUsed-1)));
}
} else {
for (DWORD i=0; i<head.biClrUsed; i++){
pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(255-i*(255/(head.biClrUsed-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;
int n=1<<bitspersample;
while (n-- > 0) {
if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) {
Palette16Bits=TRUE;
break;
}
}
// load the palette in the DIB
for (int i = (1 << bitspersample) - 1; i >= 0; i--) {
if (Palette16Bits) {
pal[i].rgbRed =(BYTE) CVT(red[i]);
pal[i].rgbGreen = (BYTE) CVT(green[i]);
pal[i].rgbBlue = (BYTE) CVT(blue[i]);
} else {
pal[i].rgbRed = (BYTE) red[i];
pal[i].rgbGreen = (BYTE) green[i];
pal[i].rgbBlue = (BYTE) blue[i];
}
}
break;
}
SetPalette(pal,head.biClrUsed); //palette assign
free(pal);
// read the tiff lines and save them in the DIB
uint32 nrow;
uint32 ys;
int line = CalculateLine(width, bitspersample * samplesperpixel);
long bitsize= TIFFStripSize(m_tif);
//verify bitsize: could be wrong if StripByteCounts is missing.
if (bitsize>(long)(head.biSizeImage*samplesperpixel)) bitsize=head.biSizeImage*samplesperpixel;
int tiled_image = TIFFIsTiled(m_tif);
uint32 tw, tl;
BYTE* tilebuf;
if (tiled_image){
TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
rowsperstrip = tl;
bitsize = TIFFTileSize(m_tif) * (int)(1+width/tw);
tilebuf = (BYTE*)malloc(TIFFTileSize(m_tif));
}
bits = (BYTE*)malloc(bitsize);
if (bits==NULL){
throw "CxImageTIF can't allocate memory";
}
for (ys = 0; ys < height; ys += rowsperstrip) {
if (info.nEscape){ // <vho> - cancel decoding
free(bits);
throw "Cancelled";
}
nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);
if (tiled_image){
uint32 imagew = TIFFScanlineSize(m_tif);
uint32 tilew = TIFFTileRowSize(m_tif);
int 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);
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), bits, nrow * line) == -1) {
free(bits);
throw "Corrupted TIFF file!";
}
}
for (y = 0; y < nrow; y++) {
long offset=(nrow-y-1)*line;
if (bitspersample==16) for (DWORD xi=0;xi<width;xi++) bits[xi+offset]=bits[xi*2+offset+1];
if (samplesperpixel==1) { //simple 8bpp image
memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,info.dwEffWidth);
} else if (samplesperpixel==2) { //8bpp image with alpha layer
int xi=0;
int ii=0;
int yi=height-ys-nrow+y;
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>=(int)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
}
int xi=0;
int ii=0;
int yi=height-ys-nrow+y;
RGBQUAD c;
int l,a,b,bitsoffset;
double p,cx,cy,cz,cr,cg,cb;
while (ii<line){
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 =(BYTE)max(0,min(255,(int)(cr*255)));
c.rgbGreen=(BYTE)max(0,min(255,(int)(cg*255)));
c.rgbBlue =(BYTE)max(0,min(255,(int)(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>=(int)width){
yi--;
xi=0;
}
}
}
}
}
free(bits);
if (tiled_image) free(tilebuf);
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;
}
}
} catch (char *message) {
strncpy(info.szLastError,message,255);
if (m_tif) TIFFClose(m_tif);
if (info.nEscape==-1) return true;
return false;
}
TIFFClose(m_tif);
return true;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageTIF::Encode(CxFile * hFile, bool bAppend)
{
try{
if (hFile==NULL) throw CXIMAGE_ERR_NOFILE;
if (pDib==NULL) 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) throw "initialization fail";
if (bAppend || m_pages) m_multipage=true;
m_pages++;
if (!EncodeBody(m_tif2,m_multipage,m_pages,m_pages)) throw "Error saving TIFF file";
if (bAppend) {
if (!TIFFWriteDirectory(m_tif2)) throw "Error saving TIFF directory";
}
} catch (char *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, int pagecount)
{
try{
if (hFile==NULL) throw "invalid file pointer";
if (pImages==NULL || pagecount==0) throw "multipage TIFF, no images!";
CxImageTIF ghost;
for (int i=1; i<=pagecount; i++){
if (pImages[i-1]==NULL) throw "Bad image pointer";
ghost.Ghost(pImages[i-1]);
if (!ghost.Encode(hFile,true)) throw "Error saving TIFF file";
}
} catch (char *message) {
strncpy(info.szLastError,message,255);
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int page, int pagecount)
{
uint32 height=head.biHeight;
uint32 width=head.biWidth;
uint16 bitcount=head.biBitCount;
uint16 bitspersample;
uint16 samplesperpixel;
uint16 photometric=0;
uint16 compression;
// uint16 pitch;
// int line;
uint32 x, y;
samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (BYTE)3 : (BYTE)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
BYTE *iSrc=info.pImage;
for (unsigned long i=0;i<head.biSizeImage;i++){
*iSrc=(BYTE)~(*(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()){
BYTE b;
memcpy(pal,GetPalette(),GetPaletteSize());
for(WORD 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 (int 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 = (WORD)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, info.nQuality);
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
BYTE *bits;
switch(bitcount) {
case 1 :
case 4 :
case 8 :
{
if (samplesperpixel==1){
for (y = 0; y < height; y++) {
bits= info.pImage + (height - y - 1)*info.dwEffWidth;
if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) return false;
}
}
#if CXIMAGE_SUPPORT_ALPHA
else { //8bpp + alpha layer
bits = (BYTE*)malloc(2*width);
if (!bits) return false;
for (y = 0; y < height; y++) {
for (x=0;x<width;x++){
bits[2*x]=GetPixelIndex(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:
{
BYTE *buffer = (BYTE *)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
BYTE *pBuf = buffer;
for (x = 0; x < width; x++) {
BYTE 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
BYTE *buffer = (BYTE *)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
BYTE *pSrc = buffer + 3 * width;
BYTE *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, int outskew, int 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);
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_TIF

View File

@ -1,60 +0,0 @@
/*
* 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 char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TIF);}
// bool Save(const char * 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, int pagecount);
bool Encode(FILE *hFile, bool bAppend=false) { CxIOFile file(hFile); return Encode(&file,bAppend); }
bool Encode(FILE *hFile, CxImage ** pImages, int pagecount)
{ CxIOFile file(hFile); return Encode(&file, pImages, pagecount); }
#endif // CXIMAGE_SUPPORT_ENCODE
protected:
void TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int outskew, int inskew);
bool EncodeBody(TIFF *m_tif, bool multipage=false, int page=0, int pagecount=0);
TIFF *m_tif2;
bool m_multipage;
int m_pages;
};
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +0,0 @@
/*
* File: ximawbmp.cpp
* Purpose: Platform Independent WBMP Image Class Loader and Writer
* 12/Jul/2002 Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximawbmp.h"
#if CXIMAGE_SUPPORT_WBMP
#include "ximaiter.h"
////////////////////////////////////////////////////////////////////////////////
bool CxImageWBMP::Decode(CxFile *hFile)
{
if (hFile == NULL) return false;
WBMPHEADER wbmpHead;
try
{
if (hFile->Read(&wbmpHead,sizeof(wbmpHead),1)==0)
throw "Not a WBMP";
if (wbmpHead.Type != 0)
throw "Unsupported WBMP type";
if (wbmpHead.ImageHeight==0 || wbmpHead.ImageWidth==0)
throw "Corrupted WBMP";
Create(wbmpHead.ImageWidth, wbmpHead.ImageHeight, 1, CXIMAGE_FORMAT_WBMP);
if (!IsValid()) throw "WBMP Create failed";
SetGrayPalette();
int linewidth=(wbmpHead.ImageWidth+7)/8;
CImageIterator iter(this);
iter.Upset();
for (int y=0; y < wbmpHead.ImageHeight; y++){
hFile->Read(iter.GetRow(),linewidth,1);
iter.PrevRow();
}
} catch (char *message) {
strncpy(info.szLastError,message,255);
return FALSE;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
bool CxImageWBMP::Encode(CxFile * hFile)
{
if (EncodeSafeCheck(hFile)) return false;
//check format limits
if ((head.biWidth>255)||(head.biHeight>255)||(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=(BYTE)head.biWidth;
wbmpHead.ImageHeight=(BYTE)head.biHeight;
// Write the file header
hFile->Write(&wbmpHead,sizeof(wbmpHead),1);
// Write the pixels
int linewidth=(wbmpHead.ImageWidth+7)/8;
CImageIterator iter(this);
iter.Upset();
for (int y=0; y < wbmpHead.ImageHeight; y++){
hFile->Write(iter.GetRow(),linewidth,1);
iter.PrevRow();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_ENCODE
////////////////////////////////////////////////////////////////////////////////
#endif // CXIMAGE_SUPPORT_WBMP

View File

@ -1,44 +0,0 @@
/*
* 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
{
BYTE Type; // 0
BYTE FixHeader; // 0
BYTE ImageWidth; // Image Width
BYTE ImageHeight; // Image Height
} WBMPHEADER;
#pragma pack()
public:
CxImageWBMP(): CxImage(CXIMAGE_FORMAT_WBMP) {}
// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_WBMP);}
// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_WBMP);}
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

View File

@ -1,458 +0,0 @@
/*
*********************************************************************
* 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
/////////////////////////////////////////////////////////////////////
bool CxImageWMF::Decode(CxFile *hFile, long nForceWidth, long nForceHeight)
{
if (hFile == NULL) return false;
HENHMETAFILE hMeta;
HDC hDC;
int cx,cy;
//save the current position of the file
long 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;
// UINT 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);
int cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
int cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
::ReleaseDC(0, hDC);
cx = (mfh.bbox.right - mfh.bbox.left) * cx1 / mfh.inch;
cy = (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 size
cx = emh.rclBounds.right - emh.rclBounds.left;
cy = emh.rclBounds.bottom - emh.rclBounds.top;
}
if (info.nEscape) { // Check if cancelled
DeleteEnhMetaFile(hMeta);
strcpy(info.szLastError,"Cancelled");
return false;
}
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};
int 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
DWORD dwBack = XMF_COLOR_BACK;
#if XMF_SUPPORT_TRANSPARENCY
if (bpp == 24) dwBack = XMF_COLOR_TRANSPARENT;
#endif
DWORD 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;
int iEntries = GetEnhMetaFilePaletteEntries(hMeta, 0, NULL);
if (iEntries) {
if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
DeleteObject(hBitmap);
DeleteDC(hDC);
DeleteEnhMetaFile(hMeta);
strcpy(info.szLastError,"Cancelled");
return false;
}
plogPal->palVersion = 0x300;
plogPal->palNumEntries = (WORD) 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,
(UINT)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)
{
WORD *pw;
WORD cs;
int i;
// check magic #
if (metafileheader->key != 0x9ac6cdd7L) return false;
// test checksum of header
pw = (WORD *)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;
long lenFile;
long len;
BYTE *p;
METAHEADER mfHeader;
DWORD 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 = (BYTE *)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;
int 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 = (metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch;
mfp.yExt = (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;
// ????
//int 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;
long iLen = pFile->Size();
BYTE* pBuff = (BYTE *)malloc(iLen);
if (!pBuff) return (FALSE);
// Read the Enhanced Metafile
long iLenRead = pFile->Read(pBuff, 1, iLen);
if (iLenRead != iLen) {
free(pBuff);
return (FALSE);
}
// Make it a Memory Metafile
hMeta = SetEnhMetaFileBits(iLen, pBuff);
free(pBuff); // finished with this one
if (!hMeta) return (FALSE); // oops.
// Get the Enhanced Metafile Header
UINT 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 (FALSE);
}
return (hMeta);
}
/////////////////////////////////////////////////////////////////////
#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(int &cx, int &cy)
{
int xScreen = XMF_MAXSIZE_CX;
int 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

View File

@ -1,154 +0,0 @@
/*
*********************************************************************
* 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
{
short int left;
short int top;
short int right;
short int bottom;
} RECT16;
// taken from Windos 3.11 SDK Documentation (Programmer's Reference Volume 4: Resources)
typedef struct tagMETAFILEHEADER
{
DWORD key; // always 0x9ac6cdd7
WORD reserved1; // reserved = 0
RECT16 bbox; // bounding rectangle in metafile units as defined in "inch"
WORD inch; // number of metafile units per inch (should be < 1440)
DWORD reserved2; // reserved = 0
WORD checksum; // sum of the first 10 WORDS (using XOR operator)
} METAFILEHEADER;
#pragma pack()
public:
CxImageWMF(): CxImage(CXIMAGE_FORMAT_WMF) { }
bool Decode(CxFile * hFile, long nForceWidth=0, long nForceHeight=0);
bool Decode(FILE *hFile, long nForceWidth=0, long 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(int &cx, int &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

File diff suppressed because it is too large Load Diff

View File

@ -1,112 +0,0 @@
#if !defined(__xiofile_h)
#define __xiofile_h
#include "xfile.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 char *filename, const char *mode)
{
if (m_fp) return false; // Can't re-open without closing first
m_fp = fopen(filename, mode);
if (!m_fp) return false;
m_bCloseFile = true;
return true;
}
//////////////////////////////////////////////////////////
virtual bool Close()
{
int 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(long offset, int origin)
{
if (!m_fp) return false;
return (bool)(fseek(m_fp, offset, origin) == 0);
}
//////////////////////////////////////////////////////////
virtual long Tell()
{
if (!m_fp) return 0;
return ftell(m_fp);
}
//////////////////////////////////////////////////////////
virtual long Size()
{
if (!m_fp) return -1;
long 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 long Error()
{
if (!m_fp) return -1;
return ferror(m_fp);
}
//////////////////////////////////////////////////////////
virtual bool PutC(unsigned char c)
{
if (!m_fp) return false;
return (bool)(fputc(c, m_fp) == c);
}
//////////////////////////////////////////////////////////
virtual long GetC()
{
if (!m_fp) return EOF;
return getc(m_fp);
}
//////////////////////////////////////////////////////////
protected:
FILE *m_fp;
bool m_bCloseFile;
};
#endif

View File

@ -1,173 +0,0 @@
#include "xmemfile.h"
//////////////////////////////////////////////////////////
CxMemFile::CxMemFile(BYTE* pBuffer, DWORD size)
{
m_pBuffer = pBuffer;
m_Position = 0;
m_Size = m_Edge = size;
m_bFreeOnClose = (bool)(pBuffer==0);
}
//////////////////////////////////////////////////////////
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=(BYTE*)malloc(1);
m_bFreeOnClose = true;
return (m_pBuffer!=0);
}
//////////////////////////////////////////////////////////
BYTE* CxMemFile::GetBuffer(bool bDetachBuffer)
{
m_bFreeOnClose = !bDetachBuffer;
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 >= (long)m_Size) return 0;
long nCount = (long)(count*size);
if (nCount == 0) return 0;
long nRead;
if (m_Position + nCount > (long)m_Size)
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)
{
if (m_pBuffer==NULL) return 0;
if (buffer==NULL) return 0;
long nCount = (long)(count*size);
if (nCount == 0) return 0;
if (m_Position + nCount > m_Edge) Alloc(m_Position + nCount);
memcpy(m_pBuffer + m_Position, buffer, nCount);
m_Position += nCount;
if (m_Position > (long)m_Size) m_Size = m_Position;
return count;
}
//////////////////////////////////////////////////////////
bool CxMemFile::Seek(long offset, int origin)
{
if (m_pBuffer==NULL) return false;
long 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;
}
//////////////////////////////////////////////////////////
long CxMemFile::Tell()
{
if (m_pBuffer==NULL) return -1;
return m_Position;
}
//////////////////////////////////////////////////////////
long 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_Position >= (long)m_Size);
}
//////////////////////////////////////////////////////////
long CxMemFile::Error()
{
if (m_pBuffer==NULL) return -1;
return (m_Position > (long)m_Size);
}
//////////////////////////////////////////////////////////
bool CxMemFile::PutC(unsigned char c)
{
if (m_pBuffer==NULL) return false;
if (m_Position + 1 > m_Edge) Alloc(m_Position + 1);
memcpy(m_pBuffer + m_Position, &c, 1);
m_Position += 1;
if (m_Position > (long)m_Size) m_Size = m_Position;
return true;
}
//////////////////////////////////////////////////////////
long CxMemFile::GetC()
{
if (Eof()) return EOF;
return *(BYTE*)((BYTE*)m_pBuffer + m_Position++);
}
//////////////////////////////////////////////////////////
void CxMemFile::Alloc(DWORD dwNewLen)
{
if (dwNewLen > (DWORD)m_Edge)
{
// find new buffer size
DWORD dwNewBufferSize = (DWORD)(((dwNewLen>>12)+1)<<12);
// allocate new buffer
if (m_pBuffer == NULL) m_pBuffer = (BYTE*)malloc(dwNewBufferSize);
else m_pBuffer = (BYTE*)realloc(m_pBuffer, dwNewBufferSize);
// I own this buffer now (caller knows nothing about it)
m_bFreeOnClose = true;
m_Edge = dwNewBufferSize;
}
return;
}
//////////////////////////////////////////////////////////
void CxMemFile::Free()
{
Close();
}
//////////////////////////////////////////////////////////

View File

@ -1,39 +0,0 @@
#if !defined(__xmemfile_h)
#define __xmemfile_h
#include "xfile.h"
//////////////////////////////////////////////////////////
class DLL_EXP CxMemFile : public CxFile
{
public:
CxMemFile(BYTE* pBuffer = NULL, DWORD size = 0);
~CxMemFile();
bool Open();
BYTE* 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(long offset, int origin);
virtual long Tell();
virtual long Size();
virtual bool Flush();
virtual bool Eof();
virtual long Error();
virtual bool PutC(unsigned char c);
virtual long GetC();
protected:
void Alloc(DWORD nBytes);
void Free();
BYTE* m_pBuffer;
DWORD m_Size;
bool m_bFreeOnClose;
long m_Position; //current position
long m_Edge; //buffer size
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
All those libraries use the Static Multi-Threaded C/C++ [Release / Debug] libraries.