pixel.cpp
来自「网络泡泡被.net管理」· C++ 代码 · 共 1,232 行 · 第 1/3 页
CPP
1,232 行
// Pixel.cpp: implementation of the CPixel class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "gslib_internal.h"
#include "PhotoshopReader.h"
#include <io.h>
#include <errno.h>
#include <assert.h>
// -----------------------------------------------------------------------------
// inlines for SPixel24
// -----------------------------------------------------------------------------
inline SPixel24::SPixel24()
{
}
inline SPixel24::SPixel24( DWORD arg )
{
blue = static_cast<BYTE>(arg);
green = static_cast<BYTE>(arg >> 8);
red = static_cast<BYTE>(arg >> 16);
}
inline SPixel24::SPixel24( BYTE new_red, BYTE new_green, BYTE new_blue )
: blue( new_blue ), green( new_green ), red( new_red )
{
}
inline SPixel24 & SPixel24::operator&=( SPixel24 right )
{
blue &= right.blue;
green &= right.green;
red &= right.red;
return *this;
}
inline SPixel24 & SPixel24::operator|=( SPixel24 right )
{
blue |= right.blue;
green |= right.green;
red |= right.red;
return *this;
}
inline SPixel24 & SPixel24::operator^=( SPixel24 right )
{
blue ^= right.blue;
green ^= right.green;
red ^= right.red;
return *this;
}
inline SPixel24::operator DWORD() const
{
return blue | (green << 8) | (red << 16);
}
// -----------------------------------------------------------------------------
// inlines for SPixel32
// -----------------------------------------------------------------------------
inline SPixel32::SPixel32()
{
}
inline SPixel32::SPixel32( BYTE new_red, BYTE new_green, BYTE new_blue, BYTE new_alpha )
: SPixel24( new_red, new_green, new_blue ), alpha( new_alpha )
{
}
inline SPixel32::SPixel32( SPixel24 const& arg ) : SPixel24( arg )
{
alpha = 255;
}
inline SPixel32::SPixel32( DWORD arg )
{
*(reinterpret_cast<DWORD*>(this)) = arg;
}
inline SPixel32 & SPixel32::operator&=( SPixel32 right )
{
*(reinterpret_cast<DWORD*>(this)) &= right;
return *this;
}
inline SPixel32 & SPixel32::operator|=( SPixel32 right )
{
*(reinterpret_cast<DWORD*>(this)) |= right;
return *this;
}
inline SPixel32 & SPixel32::operator^=( SPixel32 right )
{
*(reinterpret_cast<DWORD*>(this)) ^= right;
return *this;
}
inline SPixel32::operator DWORD() const
{
return *(reinterpret_cast<DWORD const*>(this));
}
// -----------------------------------------------------------------------------
// inline comparators
// -----------------------------------------------------------------------------
inline bool operator==( SPixel24 const& left, SPixel24 const& right )
{
return left.blue == right.blue && left.green == right.green && left.red == right.red;
}
inline bool operator!=( SPixel24 const& left, SPixel24 const& right )
{
return !( left == right );
}
inline bool operator==( SPixel32 const& left, SPixel32 const& right )
{
return DWORD( left ) == DWORD( right );
}
inline bool operator!=( SPixel32 const& left, SPixel32 const& right )
{
return !( left == right );
}
// -----------------------------------------------------------------------------
// Bitwise operators
// -----------------------------------------------------------------------------
inline SPixel24 operator&( SPixel24 left, SPixel24 right )
{
SPixel24 result( left );
result &= right;
return result;
}
inline SPixel24 operator|( SPixel24 left, SPixel24 right )
{
SPixel24 result( left );
result |= right;
return result;
}
inline SPixel24 operator^( SPixel24 left, SPixel24 right )
{
SPixel24 result( left );
result ^= right;
return result;
}
inline SPixel32 operator&( SPixel32 left, SPixel32 right )
{
SPixel32 result( left );
result &= right;
return result;
}
inline SPixel32 operator|( SPixel32 left, SPixel32 right )
{
SPixel32 result( left );
result |= right;
return result;
}
inline SPixel32 operator^( SPixel32 left, SPixel32 right )
{
SPixel32 result( left );
result ^= right;
return result;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
Field | Length | Description | Value
------|--------|-------------------------------------------- |--------------
1 | 1 | Length of Field 6 in Bytes. 0 if not present| 0
2 | 1 | Color map type. 1=present, 0=not present | 0
3 | 1 | Image type: 1=8-bit palette style | 2
| | 2=Direct [A]RGB image |
| | 3=grayscale |
| | 9=RLE version of Type 1 |
| | 10=RLE version of Type 2 |
| | 11=RLE version of Type 3 |
4.1 | 2 | Index # of first item in colormap, if any | 0 (n/a)
4.2 | 2 | Number of entries in colormap | 0 (n/a)
4.3 | 1 | Number of bits per entry (must be an even # | 0 (n/a)
| | of bytes) |
5.1 | 2 | X offset of image from *lower-left* corner | 0
5.2 | 2 | Y offset " " " " | 0
5.3 | 2 | Width of image in pixels | whatever
5.4 | 2 | Height " " | whatever
5.5 | 1 | # of bits per pixel, including Alpha (must | 24
| | be an even # of bytes) |
5.6 | 1 | Attributes: bits 0-3=# of Alpha bits per pxl| 0
| | bit 4=Reverse L-R order of pixels | 0
| | (clarified: 1st pixel stored for @ row is |
| | the rightmost pixel instead of the leftmst)|
| | bit 5=Reverse top-bottom order | 0
| | (set this bit for "bottom-up" TGA files) |
| | bits 6-7=Always 0 | 0
6 |[Fld 1] | Short description of image in ASCII format. | not present
7 | var | Colormap. Size determined by Flds 4.2 & | not present
| | 4.3. Used in Type 1 images. |
8 | var | ACTUAL IMAGE DATA. [Fld 5.3] * [Fld 5.4] | whatever
| | pixels are stored (unless RLE... see below)|
For RGB or ARGB-format TGAs, each pixel is simply stored with the Blue
bits first, and the Red bits last. If there are attribute bits, then those
follow the Red bits at the end (The Truevision docs were a little unclear
about where the attribute bits go, but I am fairly sure that they're at the
end).
TGAs can also be Run Length Encoded (RLE). Data types 9, 10, and 11 use
this method. TGA files use "packets" to store RLE data. Each packet
consists of a 1-byte info section, followed by one pixel value, which is
stored exactly as normal pixels are stored in non-RLE TGA files.
There are two types of packets, run and raw. A run packet is followed by
a single pixel value, which is repeated a specified number of times. A raw
packet is followed by a variable number of pixels, which are inserted into
the image without repetition.
This diagram will hopefully show how to decode the info byte:
7 6 5 4 3 2 1 0
+---------------------------------------+
High bit | ** | | | | | | | | Low bit
+---------------------------------------+
|====|==================================|
^ ^
| |
This bit specifies what type | If the packet is a run packet, these bits
of packet we are looking at. | tell how many times to repeat the next pixel.
0 = raw packet | If this is a raw packet, these bits tell how
1 = run packet | many pixels are in the raw packet. After that
| many pixel values, you will encounter the
| start of the next packet.
There are two catches here:
* Runs can never wrap from one row of pixels to the next (all of the
pixels in a run must have the same Y). If they did, it would screw up the
scan line table included in the Extension Area.
* THE NUMBER STORED IN THE INFO BYTE OF EACH PACKET IS ONE LESS THAN IT
SHOULD BE! Add one to the number stored in the packet in order to get the
correct value. Therefore, if the number in the byte is 0, the number of reps
(or pixels, as the case may be), is 1; if the number is 41, the actual
number of reps is 42.
This was done because there will never be a run of 0 reps or a raw packet
containing 0 pixels. Therefore, to expand the maximum length of the runs and
raw pixel strings, every value was bumped back one.
*/
/*
format for the TGA File Footer is defined as follows:
Bytes 0-3: The Extension Area Offset
Bytes 4-7: The Developer Directory Offset
Bytes 8-23: The Signature TRUEVISION-XFILE
Byte 24: ASCII Character "."
Byte 25: Binary zero suing terminator (0x00)
*/
/*
Extension Size - Field 10 (2 Bytes):................13
Author Name - Field 11 (41 Bytes):..................13
Author Comments - Field 12 (324 Bytes):.............13
Date/Time Stamp - Field 13 (12 Bytes):..............14
Job Name/ID - Field 14 (41 Bytes):..................14
Job Time - Field 15 (6 Bytes):......................14
Software ID - Field 16 (41 Bytes):..................15
Software Version - Field 17 (3 Bytes):..............15
Key Color - Field 18 (4 Bytes):.....................15
Pixel Aspect Ratio - Field 19 (4 Bytes):............16
Gamma Value - Field 20 (4 Bytes):...................16
Color Correction Offset - Field 21 (4 Bytes):.......16
Postage Stamp Offset - Field 22 (4 Bytes):..........16
Scan Line Offset - Field 23 (4 Bytes):..............17
Attributes Type - Field 24 (1 Byte):................17
Scan Line Table - Field 25 (Variable):..............18
Postage Stamp Image - Field 26 (Variable):..........18
Color Correction Table - Field 27 (2K Bytes):.......18
*/
enum t_targa_format
{
k_targa_paletted = 1,
k_targa_rgb,
k_targa_grayscale,
k_targa_has_run_length_encoding = 8,
k_targa_paletted_encoded,
k_targa_rgb_encoded,
k_targa_grayscale_encoded
};
#pragma pack(1)
namespace {
struct t_targa_header
{
BYTE description_length;
bool has_palette;
BYTE format;
WORD first_palette_index;
WORD palette_size;
BYTE bits_per_palette_entry;
short x_offset;
short y_offset;
WORD width;
WORD height;
BYTE bits_per_pixel;
BYTE flags;
};
struct t_targa_footer
{
long extension_offset;
long developer_offset;
char signature[18];
};
struct t_targa_extension
{
WORD size;
char author[41];
char comments[324];
char date[12];
char job_name[41];
char job_time[6];
char software[41];
char software_version[3];
DWORD key_color;
DWORD aspect_ratio;
DWORD gamma_value;
DWORD gamma_offset;
DWORD thumbnail_offset;
DWORD scan_line_offset;
BYTE attributes;
};
class t_get_paletted_pixel
{
public:
t_get_paletted_pixel( PIX24 const* palette )
{
m_palette = palette;
}
PIX32 operator()( fstream& buffer )
{
return m_palette[ get<BYTE>( buffer ) ];
}
protected:
PIX24 const* m_palette;
};
class t_get_rgb_pixel
{
public:
PIX32 operator()( fstream& buffer )
{
return get<PIX24>( buffer );
}
};
class t_get_rgb_alpha_pixel
{
public:
PIX32 operator()( fstream& buffer )
{
PIX24 pixel = get<PIX24>(buffer);
BYTE alpha = get<BYTE>(buffer);
return PIX32( pixel.red, pixel.green, pixel.blue, alpha );
}
};
class t_get_grayscale_pixel
{
public:
PIX32 operator()( fstream& buffer )
{
BYTE data = get<BYTE>(buffer);
return PIX32( data, data, data );
}
};
template <class t_reader>
void read_raw( fstream& buffer, PIX32* dest, int width, int delta,
t_reader reader )
{
while (width--)
{
*dest = reader( buffer );
dest += delta;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?