📄 jpeg.cpp
字号:
//+-----------------------------------------------------------------------------
//| Included files
//+-----------------------------------------------------------------------------
#include "Jpeg.h"
//+-----------------------------------------------------------------------------
//| Global objects
//+-----------------------------------------------------------------------------
JPEG Jpeg;
//+-----------------------------------------------------------------------------
//| Constructor
//+-----------------------------------------------------------------------------
JPEG::JPEG()
{
//Empty
}
//+-----------------------------------------------------------------------------
//| Destructor
//+-----------------------------------------------------------------------------
JPEG::~JPEG()
{
//Empty
}
//+-----------------------------------------------------------------------------
//| Writes JPEG data
//+-----------------------------------------------------------------------------
BOOL JPEG::Write(CONST BUFFER& SourceBuffer, BUFFER& TargetBuffer, INT Width, INT Height, INT Quality)
{
INT Stride;
INT RealSize;
INT DummySize;
BUFFER TempBuffer;
JSAMPROW Pointer[1];
jpeg_compress_struct Info;
jpeg_error_mgr ErrorManager;
Info.err = jpeg_std_error(&ErrorManager);
DummySize = ((Width * Height * 4) * 2) + 10000;
TempBuffer.Resize(DummySize);
jpeg_create_compress(&Info);
SetMemoryDestination(&Info, reinterpret_cast<UCHAR*>(TempBuffer.GetData()), TempBuffer.GetSize());
Info.image_width = Width;
Info.image_height = Height;
Info.input_components = 4;
Info.in_color_space = JCS_UNKNOWN;
jpeg_set_defaults(&Info);
jpeg_set_quality(&Info, Quality, TRUE);
jpeg_start_compress(&Info, TRUE);
Stride = Width * 4;
while(Info.next_scanline < Info.image_height)
{
Pointer[0] = reinterpret_cast<JSAMPROW>(&SourceBuffer[Info.next_scanline * Stride]);
jpeg_write_scanlines(&Info, Pointer, 1);
}
jpeg_finish_compress(&Info);
RealSize = DummySize - static_cast<INT>(Info.dest->free_in_buffer);
TargetBuffer.Resize(RealSize);
std::memcpy(&TargetBuffer[0], &TempBuffer[0], RealSize);
jpeg_destroy_compress(&Info);
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Reads JPEG data
//+-----------------------------------------------------------------------------
BOOL JPEG::Read(CONST BUFFER& SourceBuffer, BUFFER& TargetBuffer, INT* Width, INT* Height)
{
INT i;
INT Stride;
INT Offset;
CHAR Opaque;
JSAMPARRAY Pointer;
jpeg_decompress_struct Info;
jpeg_error_mgr ErrorManager;
Info.err = jpeg_std_error(&ErrorManager);
jpeg_create_decompress(&Info);
SetMemorySource(&Info, reinterpret_cast<UCHAR*>(SourceBuffer.GetData()), SourceBuffer.GetSize());
jpeg_read_header(&Info, TRUE);
jpeg_start_decompress(&Info);
if((Info.output_components != 3) && (Info.output_components != 4))
{
Error.SetMessage("Nr of channels must be 3 or 4!");
return FALSE;
}
TargetBuffer.Resize(Info.output_width * Info.output_height * 4);
Stride = Info.output_width * Info.output_components;
Offset = 0;
Pointer = (*Info.mem->alloc_sarray)(reinterpret_cast<j_common_ptr>(&Info), JPOOL_IMAGE, Stride, 1);
while(Info.output_scanline < Info.output_height)
{
jpeg_read_scanlines(&Info, Pointer, 1);
std::memcpy(&TargetBuffer[Offset], Pointer[0], Stride);
Offset += Stride;
}
jpeg_finish_decompress(&Info);
(*reinterpret_cast<BYTE*>(&Opaque)) = 255;
if(Info.output_components == 3)
{
for(i = (Info.output_width * Info.output_height - 1); i >= 0; i--)
{
TargetBuffer[(i * 4) + 3] = Opaque;
TargetBuffer[(i * 4) + 2] = TargetBuffer[(i * 3) + 2];
TargetBuffer[(i * 4) + 1] = TargetBuffer[(i * 3) + 1];
TargetBuffer[(i * 4) + 0] = TargetBuffer[(i * 3) + 0];
}
}
if(Width != NULL) (*Width) = Info.output_width;
if(Height != NULL) (*Height) = Info.output_height;
jpeg_destroy_decompress(&Info);
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Sets the memory source
//+-----------------------------------------------------------------------------
VOID JPEG::SetMemorySource(jpeg_decompress_struct* Info, UCHAR* Buffer, ULONG Size)
{
JPEG_SOURCE_MANAGER* SourceManager;
Info->src = reinterpret_cast<jpeg_source_mgr*>((*Info->mem->alloc_small)(reinterpret_cast<j_common_ptr>(Info), JPOOL_PERMANENT, sizeof(JPEG_SOURCE_MANAGER)));
SourceManager = reinterpret_cast<JPEG_SOURCE_MANAGER*>(Info->src);
SourceManager->Buffer = reinterpret_cast<JOCTET*>((*Info->mem->alloc_small)(reinterpret_cast<j_common_ptr>(Info), JPOOL_PERMANENT, Size * sizeof(JOCTET)));
SourceManager->SourceBuffer = Buffer;
SourceManager->SourceBufferSize = Size;
SourceManager->Manager.init_source = SourceInit;
SourceManager->Manager.fill_input_buffer = SourceFill;
SourceManager->Manager.skip_input_data = SourceSkip;
SourceManager->Manager.resync_to_restart = jpeg_resync_to_restart;
SourceManager->Manager.term_source = SourceTerminate;
SourceManager->Manager.bytes_in_buffer = 0;
SourceManager->Manager.next_input_byte = NULL;
}
//+-----------------------------------------------------------------------------
//| Sets the memory destination
//+-----------------------------------------------------------------------------
VOID JPEG::SetMemoryDestination(jpeg_compress_struct* Info, UCHAR* Buffer, ULONG Size)
{
JPEG_DESTINATION_MANAGER* DestinationManager;
Info->dest = reinterpret_cast<jpeg_destination_mgr*>((*Info->mem->alloc_small)(reinterpret_cast<j_common_ptr>(Info), JPOOL_PERMANENT, sizeof(JPEG_DESTINATION_MANAGER)));
DestinationManager = reinterpret_cast<JPEG_DESTINATION_MANAGER*>(Info->dest);
DestinationManager->Buffer = NULL;
DestinationManager->DestinationBuffer = Buffer;
DestinationManager->DestinationBufferSize = Size;
DestinationManager->Manager.init_destination = DestinationInit;
DestinationManager->Manager.empty_output_buffer = DestinationEmpty;
DestinationManager->Manager.term_destination = DestinationTerminate;
}
//+-----------------------------------------------------------------------------
//| Initiates the memory source
//+-----------------------------------------------------------------------------
VOID JPEG::SourceInit(jpeg_decompress_struct* Info)
{
//Empty
}
//+-----------------------------------------------------------------------------
//| Fills the memory source
//+-----------------------------------------------------------------------------
BOOLEAN JPEG::SourceFill(jpeg_decompress_struct* Info)
{
JPEG_SOURCE_MANAGER* SourceManager;
SourceManager = reinterpret_cast<JPEG_SOURCE_MANAGER*>(Info->src);
SourceManager->Buffer = SourceManager->SourceBuffer;
SourceManager->Manager.next_input_byte = SourceManager->Buffer;
SourceManager->Manager.bytes_in_buffer = SourceManager->SourceBufferSize;
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Skips the memory source
//+-----------------------------------------------------------------------------
VOID JPEG::SourceSkip(jpeg_decompress_struct* Info, LONG NrOfBytes)
{
JPEG_SOURCE_MANAGER* SourceManager;
SourceManager = reinterpret_cast<JPEG_SOURCE_MANAGER*>(Info->src);
if(NrOfBytes > 0)
{
while(NrOfBytes > static_cast<LONG>(SourceManager->Manager.bytes_in_buffer))
{
NrOfBytes -= static_cast<LONG>(SourceManager->Manager.bytes_in_buffer);
SourceFill(Info);
}
SourceManager->Manager.next_input_byte += NrOfBytes;
SourceManager->Manager.bytes_in_buffer -= NrOfBytes;
}
}
//+-----------------------------------------------------------------------------
//| Terminates the memory source
//+-----------------------------------------------------------------------------
VOID JPEG::SourceTerminate(jpeg_decompress_struct* Info)
{
//Empty
}
//+-----------------------------------------------------------------------------
//| Initiates the memory destination
//+-----------------------------------------------------------------------------
VOID JPEG::DestinationInit(jpeg_compress_struct* Info)
{
JPEG_DESTINATION_MANAGER* DestinationManager;
DestinationManager = reinterpret_cast<JPEG_DESTINATION_MANAGER*>(Info->dest);
DestinationManager->Buffer = DestinationManager->DestinationBuffer;
DestinationManager->Manager.next_output_byte = DestinationManager->Buffer;
DestinationManager->Manager.free_in_buffer = DestinationManager->DestinationBufferSize;
}
//+-----------------------------------------------------------------------------
//| Empties the memory destination
//+-----------------------------------------------------------------------------
BOOLEAN JPEG::DestinationEmpty(jpeg_compress_struct* Info)
{
JPEG_DESTINATION_MANAGER* DestinationManager;
DestinationManager = reinterpret_cast<JPEG_DESTINATION_MANAGER*>(Info->dest);
DestinationManager->Manager.next_output_byte = DestinationManager->Buffer;
DestinationManager->Manager.free_in_buffer = DestinationManager->DestinationBufferSize;
return TRUE;
}
//+-----------------------------------------------------------------------------
//| Terminates the memory destination
//+-----------------------------------------------------------------------------
VOID JPEG::DestinationTerminate(jpeg_compress_struct* Info)
{
//Empty
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -