mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-21 12:10:44 +02:00
784 lines
23 KiB
PHP
784 lines
23 KiB
PHP
{
|
|
Free Pascal port of the Hermes C library.
|
|
Copyright (C) 2001-2003 Nikolay Nikolov (nickysn@users.sourceforge.net)
|
|
Original C version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version
|
|
with the following modification:
|
|
|
|
As a special exception, the copyright holders of this library give you
|
|
permission to link this library with independent modules to produce an
|
|
executable, regardless of the license terms of these independent modules,and
|
|
to copy and distribute the resulting executable under terms of your choice,
|
|
provided that you also meet, for each linked independent module, the terms
|
|
and conditions of the license of that module. An independent module is a
|
|
module which is not derived from or based on this library. If you modify
|
|
this library, you may extend this exception to your version of the library,
|
|
but you are not obligated to do so. If you do not wish to do so, delete this
|
|
exception statement from your version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
}
|
|
|
|
{
|
|
16 bit to * converters for the HERMES library
|
|
Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
|
|
This source code is licensed under the GNU LGPL
|
|
|
|
Please refer to the file COPYING.LIB contained in the distribution for
|
|
licensing conditions
|
|
}
|
|
|
|
{ TO 32 BIT RGB }
|
|
procedure ConvertP_16rgb565_32rgb888(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
begin
|
|
repeat
|
|
d_pixel := PUint16(source)^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 3) or $030103;
|
|
|
|
PUint32(dest)^ := d_pixel;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest, 4);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
{ TO 32 BIT BGR }
|
|
procedure ConvertP_16rgb565_32bgr888(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
begin
|
|
repeat
|
|
d_pixel := PUint16(source)^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shr 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 19) or $030103;
|
|
|
|
PUint32(dest)^ := d_pixel;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest, 4);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
{ TO 32 BIT RGBA }
|
|
procedure ConvertP_16rgb565_32rgba888(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
begin
|
|
repeat
|
|
d_pixel := PUint16(source)^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 3) or $030103;
|
|
|
|
PUint32(dest)^ := (d_pixel shl 8) or $ff;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest, 4);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
{ TO 32 BIT BGRA }
|
|
procedure ConvertP_16rgb565_32bgra888(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
begin
|
|
repeat
|
|
d_pixel := PUint16(source)^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shr 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 19) or $030103;
|
|
|
|
PUint32(dest)^ := (d_pixel shl 8) or $ff;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest, 4);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
{ TO 24 BIT RGB }
|
|
procedure ConvertP_16rgb565_24rgb888(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
d_ptr: PUint8;
|
|
begin
|
|
d_ptr := PUint8(@d_pixel) + (R_32 - R_24);
|
|
repeat
|
|
d_pixel := PUint16(source)^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 3) or $030103;
|
|
|
|
(dest + 0)^ := (d_ptr + 0)^;
|
|
(dest + 1)^ := (d_ptr + 1)^;
|
|
(dest + 2)^ := (d_ptr + 2)^;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest, 3);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
{ TO 24 BIT BGR }
|
|
procedure ConvertP_16rgb565_24bgr888(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
d_ptr: PUint8;
|
|
begin
|
|
d_ptr := PUint8(@d_pixel) + (R_32 - R_24);
|
|
repeat
|
|
d_pixel := PUint16(source)^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shl 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 3) or $030103;
|
|
|
|
{ Red and blue are swapped here }
|
|
(dest + 0)^ := (d_ptr + 2)^;
|
|
(dest + 1)^ := (d_ptr + 1)^;
|
|
(dest + 2)^ := (d_ptr + 0)^;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest, 3);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
{ TO 16 BIT BGR 565 }
|
|
procedure ConvertP_16rgb565_16bgr565(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
i: DWord;
|
|
s_pixel: Uint32;
|
|
begin
|
|
{ if we are not aligned to a dword, try and convert a single pixel }
|
|
if (PtrUInt(dest) and $3) <> 0 then
|
|
begin
|
|
s_pixel := PUint16(source)^;
|
|
|
|
{ Swap around R and B, leave G unchanged }
|
|
s_pixel := (s_pixel shr 11) or (s_pixel and $7e0) or
|
|
((s_pixel shl 11) and $f800);
|
|
|
|
PUint16(dest)^ := s_pixel;
|
|
|
|
Dec(count);
|
|
Inc(dest, 2); Inc(source, 2);
|
|
end;
|
|
|
|
{ Now copy blocks of dwords }
|
|
for i := 1 to count shr 1 do
|
|
begin
|
|
s_pixel := PUint32(source)^;
|
|
|
|
{ Leave G unchanged, shift R to the right and B to the left }
|
|
s_pixel := (s_pixel and $07e007e0) or ((s_pixel and $f800f800) shr 11) or
|
|
((s_pixel and $001f001f) shl 11);
|
|
|
|
PUint32(dest)^ := s_pixel;
|
|
Inc(source, 4); Inc(dest, 4);
|
|
end;
|
|
|
|
if (count and 1) <> 0 then
|
|
begin
|
|
s_pixel := PUint16(source)^;
|
|
|
|
{ Swap around R and B, leave G unchanged }
|
|
s_pixel := (s_pixel shr 11) or (s_pixel and $7e0) or
|
|
((s_pixel shl 11) and $f800);
|
|
|
|
PUint16(dest)^ := s_pixel;
|
|
end;
|
|
end;
|
|
|
|
{ TO 16 BIT RGB 555 }
|
|
procedure ConvertP_16rgb565_16rgb555(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
i: DWord;
|
|
s_pixel: Uint32;
|
|
begin
|
|
{ if we are not aligned to a dword, try and convert a single pixel }
|
|
if (PtrUInt(dest) and $3) <> 0 then
|
|
begin
|
|
s_pixel := PUint16(source)^;
|
|
|
|
{ Leave blue untouched, mask red and shift by one, mask green and shift
|
|
by one }
|
|
s_pixel := (s_pixel and $1f) or ((s_pixel and $f800) shr 1) or
|
|
((s_pixel and $7c0) shr 1);
|
|
|
|
PUint16(dest)^ := s_pixel;
|
|
|
|
Dec(count);
|
|
Inc(dest, 2); Inc(source, 2);
|
|
end;
|
|
|
|
{ Now copy blocks of dwords }
|
|
for i := 1 to count shr 1 do
|
|
begin
|
|
s_pixel := PUint32(source)^;
|
|
|
|
{ Leave blue untouched, mask red and shift by one, mask green and shift
|
|
by one }
|
|
s_pixel := (s_pixel and $001f001f) or ((s_pixel and $f800f800) shr 1) or
|
|
((s_pixel and $07c007c0) shr 1);
|
|
|
|
PUint32(dest)^ := s_pixel;
|
|
Inc(source, 4); Inc(dest, 4);
|
|
end;
|
|
|
|
if (count and 1) <> 0 then
|
|
begin
|
|
s_pixel := PUint16(source)^;
|
|
|
|
{ Leave blue untouched, mask red and shift by one, mask green and shift
|
|
by one }
|
|
s_pixel := (s_pixel and $1f) or ((s_pixel and $f800) shr 1) or
|
|
((s_pixel and $7c0) shr 1);
|
|
|
|
PUint16(dest)^ := s_pixel;
|
|
end;
|
|
end;
|
|
|
|
{ TO 16 BIT BGR 555 }
|
|
procedure ConvertP_16rgb565_16bgr555(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
i: DWord;
|
|
s_pixel: Uint32;
|
|
begin
|
|
{ if we are not aligned to a dword, try and convert a single pixel }
|
|
if (PtrUInt(dest) and $3) <> 0 then
|
|
begin
|
|
s_pixel := PUint16(source)^;
|
|
|
|
{ Shift red right by 11, mask green and shift right one, shift blue
|
|
left ten }
|
|
s_pixel := ((s_pixel and $f800) shr 11) or ((s_pixel and $7c0) shr 1) or
|
|
((s_pixel and $1f) shl 10);
|
|
|
|
PUint16(dest)^ := s_pixel;
|
|
|
|
Dec(count);
|
|
Inc(dest, 2); Inc(source, 2);
|
|
end;
|
|
|
|
{ Now copy blocks of dwords }
|
|
for i := 1 to count shr 1 do
|
|
begin
|
|
s_pixel := PUint32(source)^;
|
|
|
|
{ Shift red right by 11, mask green and shift right one, shift blue
|
|
left ten }
|
|
s_pixel := ((s_pixel and $f800f800) shr 11) or
|
|
((s_pixel and $07c007c0) shr 1) or
|
|
((s_pixel and $001f001f) shl 10);
|
|
|
|
PUint32(dest)^ := s_pixel;
|
|
Inc(source, 4); Inc(dest, 4);
|
|
end;
|
|
|
|
if (count and 1) <> 0 then
|
|
begin
|
|
s_pixel := PUint16(source)^;
|
|
|
|
{ Shift red right by 11, mask green and shift right one, shift blue
|
|
left ten }
|
|
s_pixel := ((s_pixel and $f800) shr 11) or ((s_pixel and $7c0) shr 1) or
|
|
((s_pixel and $1f) shl 10);
|
|
|
|
PUint16(dest)^ := s_pixel;
|
|
end;
|
|
end;
|
|
|
|
{ TO 8 BIT RGB 332 }
|
|
procedure ConvertP_16rgb565_8rgb332(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
s_block, d_block: Uint32;
|
|
i: DWord;
|
|
begin
|
|
{ Align to dword first }
|
|
while (PtrUInt(dest) and $3) <> 0 do
|
|
begin
|
|
s_block := PUint16(source)^;
|
|
|
|
s_block := ((s_block and $e000) shr 8) or ((s_block and $0700) shr 6) or
|
|
((s_block and $18) shr 3);
|
|
|
|
dest^ := s_block;
|
|
|
|
Dec(count);
|
|
if count = 0 then
|
|
exit;
|
|
|
|
Inc(source, 2);
|
|
Inc(dest);
|
|
end;
|
|
|
|
{ Write blocks of four pixels }
|
|
for i := 1 to count shr 2 do
|
|
begin
|
|
{ Read and process first two pixels }
|
|
s_block := PUint32(source)^;
|
|
|
|
d_block := ((s_block and $e000e000) shr 8) or
|
|
((s_block and $07000700) shr 6) or
|
|
((s_block and $00180018) shr 3);
|
|
d_block := (d_block and $ff) or ((d_block and $ff0000) shr 8);
|
|
|
|
{ and the second two }
|
|
s_block := (PUint32(source)+1)^;
|
|
|
|
s_block := ((s_block and $e000e000) shr 8) or
|
|
((s_block and $07000700) shr 6) or
|
|
((s_block and $00180018) shr 3);
|
|
s_block := (s_block and $ff) or ((s_block and $ff0000) shr 8);
|
|
|
|
{ Put it all in one dword and write it }
|
|
d_block := (d_block shl DWORD_SMALLINT0_SHL) or (s_block shl DWORD_SMALLINT1_SHL);
|
|
|
|
PUint32(dest)^ := d_block;
|
|
Inc(source, 8);
|
|
Inc(dest, 4);
|
|
end;
|
|
|
|
{ Clean up remaining pixels }
|
|
count := count and 3;
|
|
while count > 0 do
|
|
begin
|
|
Dec(count);
|
|
s_block := PUint16(source)^;
|
|
|
|
dest^ := ((s_block and $e000) shr 8) or ((s_block and $0700) shr 6) or
|
|
((s_block and $18) shr 3);
|
|
Inc(dest);
|
|
Inc(source, 2);
|
|
end;
|
|
end;
|
|
|
|
{ -------------------------------------------------------------------------
|
|
|
|
STRETCH CONVERTERS
|
|
|
|
------------------------------------------------------------------------- }
|
|
|
|
|
|
procedure ConvertP_16rgb565_32rgb888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x: DWord;
|
|
p: Uint32;
|
|
begin
|
|
x := 0;
|
|
repeat
|
|
p := (((PUint16(source) + (x shr 16))^ and $f800) shl 8) or
|
|
(((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 3) or $30103;
|
|
|
|
Inc(x, inc_source);
|
|
|
|
PUint32(dest)^ := p;
|
|
|
|
Inc(dest, 4);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_32bgr888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
x: DWord;
|
|
begin
|
|
x := 0;
|
|
|
|
repeat
|
|
d_pixel := (PUint16(source) + (x shr 16))^;
|
|
|
|
d_pixel := ((d_pixel and $f800) shr 8) or ((d_pixel and $7e0) shl 5) or
|
|
((d_pixel and $1f) shl 19) or $30103;
|
|
|
|
PUint32(dest)^ := d_pixel;
|
|
|
|
Inc(dest, 4);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_32rgba888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x: DWord;
|
|
p: Uint32;
|
|
begin
|
|
x := 0;
|
|
repeat
|
|
p := (((PUint16(source) + (x shr 16))^ and $f800) shl (8+8)) or
|
|
(((PUint16(source) + (x shr 16))^ and $7e0) shl (5+8)) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl (3+8)) or $30103ff;
|
|
|
|
Inc(x, inc_source);
|
|
|
|
PUint32(dest)^ := p;
|
|
|
|
Inc(dest, 4);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_32bgra888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
d_pixel: Uint32;
|
|
x: DWord;
|
|
begin
|
|
x := 0;
|
|
|
|
repeat
|
|
d_pixel := (PUint16(source) + (x shr 16))^;
|
|
|
|
d_pixel := ((d_pixel and $f800) {Shr 8}) or ((d_pixel and $7e0) shl (5+8)) or
|
|
((d_pixel and $1f) shl (19+8)) or $30103ff;
|
|
|
|
PUint32(dest)^ := d_pixel;
|
|
|
|
Inc(dest, 4);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
until count = 0;
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_24rgb888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x: DWord;
|
|
p1, p2, p3, p4: DWord;
|
|
c: DWord;
|
|
begin
|
|
x := 0;
|
|
while (PtrUInt(dest) and 3) <> 0 do
|
|
begin
|
|
p1 := (((PUint16(source) + (x shr 16))^ and $f800) shl 8) or
|
|
(((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 3) or $30103;
|
|
(dest + B_24)^ := p1 and $FF;
|
|
(dest + G_24)^ := (p1 shr 8) and $FF;
|
|
(dest + R_24)^ := p1 shr 16;
|
|
|
|
Inc(dest, 3);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
if count = 0 then
|
|
exit;
|
|
end;
|
|
|
|
c := count shr 2;
|
|
while c > 0 do
|
|
begin
|
|
p1 := (PUint16(source) + (x shr 16))^;
|
|
p2 := (PUint16(source) + ((x + inc_source) shr 16))^;
|
|
p3 := (PUint16(source) + ((x + 2*inc_source) shr 16))^;
|
|
p4 := (PUint16(source) + ((x + 3*inc_source) shr 16))^;
|
|
|
|
{$IFDEF FPC_LITTLE_ENDIAN}
|
|
PUint32(dest + 0)^ := ((p2 and $001F) shl 27) or ((p1 and $F800) shl 8) or ((p1 and $07E0) shl 5) or ((p1 and $001F) shl 3) or $03030103;
|
|
PUint32(dest + 4)^ := ((p3 and $07E0) shl 21) or ((p3 and $001F) shl 19) or (p2 and $F800) or ((p2 and $07E0) shr 3) or $01030301;
|
|
PUint32(dest + 8)^ := ((p4 and $F800) shl 16) or ((p4 and $07E0) shl 13) or ((p4 and $001F) shl 11) or ((p3 and $F800) shr 8) or $03010303;
|
|
{$ELSE FPC_LITTLE_ENDIAN}
|
|
PUint32(dest + 0)^ := ((p1 and $F800) shl 16) or ((p1 and $07E0) shl 13) or ((p1 and $001F) shl 11) or ((p2 and $F800) shr 8) or $03010303;
|
|
PUint32(dest + 4)^ := ((p2 and $07E0) shl 21) or ((p2 and $001F) shl 19) or (p3 and $F800) or ((p3 and $07E0) shr 3) or $01030301;
|
|
PUint32(dest + 8)^ := ((p3 and $001F) shl 27) or ((p4 and $F800) shl 8) or ((p4 and $07E0) shl 5) or ((p4 and $001F) shl 3) or $03030103;
|
|
{$ENDIF FPC_LITTLE_ENDIAN}
|
|
|
|
Inc(x, 4*inc_source);
|
|
Inc(dest, 12);
|
|
Dec(c);
|
|
end;
|
|
|
|
count := count and 3;
|
|
while count > 0 do
|
|
begin
|
|
p1 := (((PUint16(source) + (x shr 16))^ and $f800) shl 8) or
|
|
(((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 3) or $30103;
|
|
(dest + B_24)^ := p1 and $FF;
|
|
(dest + G_24)^ := (p1 shr 8) and $FF;
|
|
(dest + R_24)^ := p1 shr 16;
|
|
|
|
Inc(dest, 3);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
end;
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_24bgr888_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x: DWord;
|
|
p1, p2, p3, p4: DWord;
|
|
c: DWord;
|
|
begin
|
|
x := 0;
|
|
while (PtrUInt(dest) and 3) <> 0 do
|
|
begin
|
|
p1 := (((PUint16(source) + (x shr 16))^ and $f800) shr 8) or
|
|
(((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 19) or $30103;
|
|
(dest + B_24)^ := p1 and $FF;
|
|
(dest + G_24)^ := (p1 shr 8) and $FF;
|
|
(dest + R_24)^ := p1 shr 16;
|
|
|
|
Inc(dest, 3);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
if count = 0 then
|
|
exit;
|
|
end;
|
|
|
|
c := count shr 2;
|
|
while c > 0 do
|
|
begin
|
|
p1 := (PUint16(source) + (x shr 16))^;
|
|
p2 := (PUint16(source) + ((x + inc_source) shr 16))^;
|
|
p3 := (PUint16(source) + ((x + 2*inc_source) shr 16))^;
|
|
p4 := (PUint16(source) + ((x + 3*inc_source) shr 16))^;
|
|
|
|
{$IFDEF FPC_LITTLE_ENDIAN}
|
|
PUint32(dest + 0)^ := ((p2 and $F800) shl 16) or ((p1 and $001F) shl 19) or ((p1 and $07E0) shl 5) or ((p1 and $F800) shr 8) or $03030103;
|
|
PUint32(dest + 4)^ := ((p3 and $07E0) shl 21) or ((p3 and $F800) shl 8) or ((p2 and $001F) shl 11) or ((p2 and $07E0) shr 3) or $01030301;
|
|
PUint32(dest + 8)^ := ((p4 and $001F) shl 27) or ((p4 and $07E0) shl 13) or (p4 and $F800) or ((p3 and $001F) shl 3) or $03010303;
|
|
{$ELSE FPC_LITTLE_ENDIAN}
|
|
PUint32(dest + 0)^ := ((p1 and $001F) shl 27) or ((p1 and $07E0) shl 13) or (p1 and $F800) or ((p2 and $001F) shl 3) or $03010303;
|
|
PUint32(dest + 4)^ := ((p2 and $07E0) shl 21) or ((p2 and $F800) shl 8) or ((p3 and $001F) shl 11) or ((p3 and $07E0) shr 3) or $01030301;
|
|
PUint32(dest + 8)^ := ((p3 and $F800) shl 16) or ((p4 and $001F) shl 19) or ((p4 and $07E0) shl 5) or ((p4 and $F800) shr 8) or $03030103;
|
|
{$ENDIF FPC_LITTLE_ENDIAN}
|
|
|
|
Inc(x, 4*inc_source);
|
|
Inc(dest, 12);
|
|
Dec(c);
|
|
end;
|
|
|
|
count := count and 3;
|
|
while count > 0 do
|
|
begin
|
|
p1 := (((PUint16(source) + (x shr 16))^ and $f800) shr 8) or
|
|
(((PUint16(source) + (x shr 16))^ and $7e0) shl 5) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 19) or $30103;
|
|
(dest + B_24)^ := p1 and $FF;
|
|
(dest + G_24)^ := (p1 shr 8) and $FF;
|
|
(dest + R_24)^ := p1 shr 16;
|
|
|
|
Inc(dest, 3);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
end;
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_16bgr565_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x, c: DWord;
|
|
p: Uint32;
|
|
begin
|
|
x := 0;
|
|
{ if we are not aligned to a dword, try and convert a single pixel }
|
|
if (PtrUInt(dest) and $3) <> 0 then
|
|
begin
|
|
{ Swap r and b, leave g untouched }
|
|
PUint16(dest)^ := ((PUint16(source) + (x shr 16))^ shr 11) or
|
|
((PUint16(source) + (x shr 16))^ and $7e0) or
|
|
(((PUint16(source) + (x shr 16))^ shl 11) and $f800);
|
|
Inc(x, inc_source);
|
|
Inc(dest, 2);
|
|
Dec(count);
|
|
end;
|
|
|
|
c := count shr 1;
|
|
while c <> 0 do
|
|
begin
|
|
Dec(c);
|
|
|
|
{ Swap r and b, leave g untouched }
|
|
p := (((PUint16(source) + (x shr 16))^ shr 11) or
|
|
((PUint16(source) + (x shr 16))^ and $7e0) or
|
|
(((PUint16(source) + (x shr 16))^ shl 11) and $f800)) shl DWORD_SMALLINT0_SHL;
|
|
Inc(x, inc_source);
|
|
|
|
p := p or ((((PUint16(source) + (x shr 16))^ shr 11) or
|
|
((PUint16(source) + (x shr 16))^ and $7e0) or
|
|
(((PUint16(source) + (x shr 16))^ shl 11) and $f800)) shl DWORD_SMALLINT1_SHL);
|
|
Inc(x, inc_source);
|
|
|
|
PUint32(dest)^ := p;
|
|
Inc(dest, 4);
|
|
end;
|
|
|
|
if (count and 1) <> 0 then
|
|
PUint16(dest)^ := ((PUint16(source) + (x shr 16))^ shr 11) or
|
|
((PUint16(source) + (x shr 16))^ and $7e0) or
|
|
(((PUint16(source) + (x shr 16))^ shl 11) and $f800);
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_16rgb555_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x, c: DWord;
|
|
p: Uint32;
|
|
begin
|
|
x := 0;
|
|
{ if we are not aligned to a dword, try and convert a single pixel }
|
|
if (PtrUInt(dest) and $3) <> 0 then
|
|
begin
|
|
PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
((PUint16(source) + (x shr 16))^ and $1f);
|
|
Inc(dest, 2);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
end;
|
|
|
|
c := count shr 1;
|
|
while c <> 0 do
|
|
begin
|
|
Dec(c);
|
|
|
|
{ Leave blue untouched, mask red and shift by one, mask green and shift
|
|
by one }
|
|
p := ((((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
((PUint16(source) + (x shr 16))^ and $1f)) shl DWORD_SMALLINT0_SHL;
|
|
Inc(x, inc_source);
|
|
|
|
p := p or (((((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
((PUint16(source) + (x shr 16))^ and $1f)) shl DWORD_SMALLINT1_SHL);
|
|
Inc(x, inc_source);
|
|
|
|
PUint32(dest)^ := p;
|
|
Inc(dest, 4);
|
|
end;
|
|
|
|
if (count and 1) <> 0 then
|
|
PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
((PUint16(source) + (x shr 16))^ and $1f);
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_16bgr555_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x, c: DWord;
|
|
p: Uint32;
|
|
begin
|
|
x := 0;
|
|
{ if we are not aligned to a dword, try and convert a single pixel }
|
|
if (PtrUInt(dest) and $3) <> 0 then
|
|
begin
|
|
PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 10);
|
|
Inc(dest, 2);
|
|
Inc(x, inc_source);
|
|
Dec(count);
|
|
end;
|
|
|
|
c := count shr 1;
|
|
while c <> 0 do
|
|
begin
|
|
Dec(c);
|
|
|
|
p := ((((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 10)) shl DWORD_SMALLINT0_SHL;
|
|
Inc(x, inc_source);
|
|
|
|
p := p or (((((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 10)) shl DWORD_SMALLINT1_SHL);
|
|
Inc(x, inc_source);
|
|
|
|
PUint32(dest)^ := p;
|
|
Inc(dest, 4);
|
|
end;
|
|
|
|
if (count and 1) <> 0 then
|
|
PUint16(dest)^ := (((PUint16(source) + (x shr 16))^ and $f800) shr 11) or
|
|
(((PUint16(source) + (x shr 16))^ and $7c0) shr 1) or
|
|
(((PUint16(source) + (x shr 16))^ and $1f) shl 10);
|
|
end;
|
|
|
|
procedure ConvertP_16rgb565_8rgb332_S(source, dest: PUint8; count, inc_source: DWord); cdecl;
|
|
var
|
|
x, c: DWord;
|
|
p: Uint32;
|
|
begin
|
|
x := 0;
|
|
|
|
{ Write single pixels until the destination address is aligned mod 4 }
|
|
while (PtrUInt(dest) and $3) <> 0 do
|
|
begin
|
|
dest^ := (((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
|
|
(((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
|
|
(((PUint16(source) + (x shr 16))^ shr 3) and $3);
|
|
Inc(x, inc_source);
|
|
Inc(dest);
|
|
Dec(count);
|
|
if count = 0 then
|
|
exit;
|
|
end;
|
|
|
|
|
|
{* Write blocks of four pixels now }
|
|
c := count shr 2;
|
|
while c <> 0 do
|
|
begin
|
|
Dec(c);
|
|
p := ((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
|
|
(((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
|
|
(((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE0_SHL;
|
|
Inc(x, inc_source);
|
|
|
|
p := p or
|
|
(((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
|
|
(((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
|
|
(((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE1_SHL);
|
|
Inc(x, inc_source);
|
|
|
|
p := p or
|
|
(((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
|
|
(((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
|
|
(((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE2_SHL);
|
|
Inc(x, inc_source);
|
|
|
|
p := p or
|
|
(((((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
|
|
(((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
|
|
(((PUint16(source) + (x shr 16))^ shr 3) and $3)) shl DWORD_BYTE3_SHL);
|
|
Inc(x, inc_source);
|
|
|
|
PUint32(dest)^ := p;
|
|
|
|
Inc(dest, 4);
|
|
end;
|
|
|
|
{ Write up to three trailing pixels }
|
|
c := count and $3;
|
|
while c <> 0 do
|
|
begin
|
|
Dec(c);
|
|
dest^ := (((PUint16(source) + (x shr 16))^ shr 8) and $e0) or
|
|
(((PUint16(source) + (x shr 16))^ shr 6) and $1c) or
|
|
(((PUint16(source) + (x shr 16))^ shr 3) and $3);
|
|
Inc(x, inc_source);
|
|
Inc(dest);
|
|
end;
|
|
end;
|