1873 lines
55 KiB
Plaintext
1873 lines
55 KiB
Plaintext
(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *)
|
|
(*
|
|
Copyright (c) 1998-2017 by Carlotta Calandra. All rights reserved.
|
|
Copyright (c) 2011-2017 by Xequte Software.
|
|
|
|
This software comes without express or implied warranty.
|
|
In no case shall the author be liable for any damage or unwanted behavior of any
|
|
computer hardware and/or software.
|
|
|
|
Author grants you the right to include the component
|
|
in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE.
|
|
|
|
ImageEn, IEvolution and ImageEn ActiveX may not be included in any
|
|
commercial, shareware or freeware libraries or components.
|
|
|
|
www.ImageEn.com
|
|
*)
|
|
|
|
(*
|
|
File version 1010
|
|
*)
|
|
|
|
unit iej2000;
|
|
|
|
{$R-}
|
|
{$Q-}
|
|
|
|
|
|
{$I ie.inc}
|
|
|
|
|
|
{$ifdef IEINCLUDEJPEG2000}
|
|
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
uses
|
|
Windows, Graphics, Classes, SysUtils, ImageEnIO, hyiedefs, iexBitmaps;
|
|
|
|
|
|
{$ifndef IEUSEDLLJPEG2000LIB}
|
|
|
|
var
|
|
__turboFloat: LongBool = False;
|
|
|
|
{$endif}
|
|
|
|
|
|
|
|
function J2KTryStreamJP2(Stream: TStream): boolean;
|
|
function J2KTryStreamJ2K(Stream: TStream): boolean;
|
|
procedure J2KReadStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var xProgress: TProgressRec; Preview: boolean);
|
|
procedure J2KWriteStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var xProgress: TProgressRec; format: integer);
|
|
|
|
procedure IEFinalize_iej2000;
|
|
|
|
type
|
|
EIEJPEG2000Exception = class(Exception);
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
ieview, imageenproc, ievision, iesettings, hyieutils;
|
|
|
|
|
|
const
|
|
IEJAS_IMAGE_CS_UNKNOWN = 0;
|
|
IEJAS_IMAGE_CS_GRAY = 1; // Standard Gray
|
|
IEJAS_IMAGE_CS_RGB = 2; // Standard RGB
|
|
IEJAS_IMAGE_CS_YCBCR = 3; // Standard YCC
|
|
|
|
IEJAS_IMAGE_CT_RGB_R = 0;
|
|
IEJAS_IMAGE_CT_RGB_G = 1;
|
|
IEJAS_IMAGE_CT_RGB_B = 2;
|
|
IEJAS_IMAGE_CT_YCBCR_Y = 0;
|
|
IEJAS_IMAGE_CT_YCBCR_CB = 1;
|
|
IEJAS_IMAGE_CT_YCBCR_CR = 2;
|
|
IEJAS_IMAGE_CT_GRAY_Y = 0;
|
|
|
|
IEJAS_IMAGE_CT_OPACITY = $8000;
|
|
|
|
|
|
|
|
procedure IEInitialize_iej2000; forward;
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// static Jasper library wrappers
|
|
|
|
|
|
{$ifndef IEUSEDLLJPEG2000LIB}
|
|
|
|
|
|
|
|
|
|
{$RANGECHECKS OFF}
|
|
|
|
{$Z4}
|
|
|
|
type
|
|
|
|
pjas_stream_t = pointer;
|
|
pjas_image_t = pointer;
|
|
pjas_matrix_t = pointer;
|
|
|
|
jas_image_cmptparm_t = record
|
|
tlx: dword; //* The x-coordinate of the top-left corner of the component. */
|
|
tly: dword; //* The y-coordinate of the top-left corner of the component. */
|
|
hstep: dword; //* The horizontal sampling period in units of the reference grid. */
|
|
vstep: dword; //* The vertical sampling period in units of the reference grid. */
|
|
width: dword; //* The width of the component in samples. */
|
|
height: dword; //* The height of the component in samples. */
|
|
prec: word; //* The precision of the component sample data. */
|
|
sgnd: integer; //* The signedness of the component sample data. */
|
|
end;
|
|
|
|
pjas_image_cmptparm_t = ^jas_image_cmptparm_t;
|
|
jas_image_cmptparm_t_array = array[0..8192] of jas_image_cmptparm_t;
|
|
pjas_image_cmptparm_t_array = ^jas_image_cmptparm_t_array;
|
|
|
|
/////// from jas
|
|
|
|
// initialization
|
|
procedure jas_init; external;
|
|
|
|
// streams
|
|
function jas_stream_fopen(filename, omode: PAnsiChar): pjas_stream_t; external;
|
|
procedure jas_stream_close(jstream: pjas_stream_t); external;
|
|
procedure jas_stream_flush(jstream: pjas_stream_t); external;
|
|
|
|
// Get the format of image data in a stream.
|
|
function jas_image_getfmt(jstream: pjas_stream_t): integer; external;
|
|
|
|
// Create an image from a stream in some specified format.
|
|
function jas_image_decode(jstream: pjas_stream_t; infmt: integer; inopts: PAnsiChar): pjas_image_t; external;
|
|
|
|
// Write an image to a stream in a specified format.
|
|
function jas_image_encode(image: pjas_image_t; jstream: pjas_stream_t; fmt: integer; optstr: PAnsiChar): integer; external;
|
|
|
|
// Delete a component from an image.
|
|
procedure jas_image_delcmpt(image: pjas_image_t; i: word); external;
|
|
|
|
// Read a rectangular region of an image component.
|
|
// The position and size of the rectangular region to be read is specified
|
|
// relative to the component's coordinate system.
|
|
function jas_image_readcmpt(image: pjas_image_t; cmptno: word; x, y, width, height: integer; data: pjas_matrix_t): integer; external;
|
|
|
|
// matrix (components)
|
|
function jas_matrix_create(numrows, numcols: integer): pjas_matrix_t; external;
|
|
procedure jas_matrix_destroy(matrix: pjas_matrix_t); external;
|
|
|
|
// Deallocate any resources associated with an image.
|
|
procedure jas_image_destroy(image: pjas_image_t); external;
|
|
|
|
// Clear the table of image formats.
|
|
procedure jas_image_clearfmts; external;
|
|
|
|
// Get the ID for the image format with the specified name.
|
|
function jas_image_strtofmt(s: PAnsiChar): integer; external;
|
|
|
|
// Get the name of the image format with the specified ID.
|
|
function jas_image_fmttostr(fmt: integer): PAnsiChar; external;
|
|
|
|
// Create an image.
|
|
function jas_image_create(numcmpts: word; cmptparms: pjas_image_cmptparm_t_array; colormodel: integer): pjas_image_t; external;
|
|
|
|
function jas_image_create0: pjas_image_t; external;
|
|
|
|
function jas_image_addcmpt(image: pjas_image_t; cmptno: word; cmptparm: pjas_image_cmptparm_t): integer; external;
|
|
|
|
function jas_image_getcmptbytype(image: pjas_image_t; ctype: integer): integer; external;
|
|
|
|
function jas_getdbglevel: integer; external;
|
|
|
|
function jas_setdbglevel(dbglevel: integer): integer; external;
|
|
|
|
procedure jas_image_writecmptsample(image: pjas_image_t; cmptno: integer; x, y: integer; v: dword); external;
|
|
|
|
procedure iejas_image_setcmpttype(image: pjas_image_t; cmptno: integer; ctype: integer); external;
|
|
|
|
//// end from jas
|
|
|
|
//// from xlib
|
|
|
|
// [IMAGE] Get the number of image components.
|
|
function iejas_image_numcmpts(image: pjas_image_t): integer; external;
|
|
|
|
// [IMAGE] The x-coordinate of the top-left corner of the image bounding box.
|
|
function iejas_image_getleft(image: pjas_image_t): integer; external;
|
|
|
|
// [IMAGE] The y-coordinate of the top-left corner of the image bounding box.
|
|
function iejas_image_gettop(image: pjas_image_t): integer; external;
|
|
|
|
// [IMAGE] The x-coordinate of the bottom-right corner of the image bounding box (plus one).
|
|
function iejas_image_getright(image: pjas_image_t): integer; external;
|
|
|
|
// [IMAGE] The y-coordinate of the bottom-right corner of the image bounding box (plus one).
|
|
function iejas_image_getbottom(image: pjas_image_t): integer; external;
|
|
|
|
// [MATRIX] get i,j value of the
|
|
function iejas_matrix_get(matrix: pjas_matrix_t; i, j: integer): integer; external;
|
|
|
|
// [IMAGE] Get the width of a component.
|
|
function iejas_image_cmptwidth(image: pjas_image_t; compno: integer): integer; external;
|
|
|
|
// [IMAGE] Get the height of a component.
|
|
function iejas_image_cmptheight(image: pjas_image_t; compno: integer): integer; external;
|
|
|
|
// [IMAGE] Get the precision of the sample data for a component.
|
|
function iejas_image_cmptprec(image: pjas_image_t; compno: integer): integer; external;
|
|
|
|
// [IMAGE] Get the width of the image in units of the image reference grid.
|
|
function iejas_image_width(image: pjas_image_t): integer; external;
|
|
|
|
// [IMAGE] Get the height of the image in units of the image reference grid.
|
|
function iejas_image_height(image: pjas_image_t): integer; external;
|
|
|
|
// [IMAGE] Get the color model used by the image.
|
|
function iejas_image_colorspace(image: pjas_image_t): integer; external;
|
|
|
|
procedure iejas_image_setcolorspace(image: pjas_image_t; colorspace: integer); external;
|
|
|
|
// [IMAGE] Get the x-coordinate of the top-left corner of a component.
|
|
function iejas_image_cmpttlx(image: pjas_image_t; cmptno: integer): integer; external;
|
|
|
|
// [IMAGE] Get the y-coordinate of the top-left corner of a component.
|
|
function iejas_image_cmpttly(image: pjas_image_t; cmptno: integer): integer; external;
|
|
|
|
// [IMAGE] Get the horizontal subsampling factor for a component
|
|
function iejas_image_cmpthstep(image: pjas_image_t; cmptno: integer): integer; external;
|
|
|
|
// [IMAGE] Get the vertical subsampling factor for a component.
|
|
function iejas_image_cmptvstep(image: pjas_image_t; cmptno: integer): integer; external;
|
|
|
|
///// end xlib
|
|
|
|
// color spaces
|
|
const
|
|
|
|
|
|
|
|
JPC_NUMAGGCTXS = 1;
|
|
JPC_NUMZCCTXS = 9;
|
|
JPC_NUMMAGCTXS = 3;
|
|
JPC_NUMSCCTXS = 5;
|
|
JPC_NUMUCTXS = 1;
|
|
JPC_AGGCTXNO = 0;
|
|
JPC_ZCCTXNO = (JPC_AGGCTXNO + JPC_NUMAGGCTXS);
|
|
JPC_MAGCTXNO = (JPC_ZCCTXNO + JPC_NUMZCCTXS);
|
|
JPC_SCCTXNO = (JPC_MAGCTXNO + JPC_NUMMAGCTXS);
|
|
JPC_UCTXNO = (JPC_SCCTXNO + JPC_NUMSCCTXS);
|
|
JPC_NUMCTXS = (JPC_UCTXNO + JPC_NUMUCTXS);
|
|
|
|
var
|
|
_jpc_zcctxnolut: array[0..4 * 256] of integer;
|
|
_jpc_spblut: array[0..256] of integer;
|
|
_jpc_scctxnolut: array[0..256] of integer;
|
|
_jpc_magctxnolut: array[0..4096] of integer;
|
|
_jpc_signmsedec: array[0..128] of integer;
|
|
_jpc_refnmsedec: array[0..128] of integer;
|
|
_jpc_signmsedec0: array[0..128] of integer;
|
|
_jpc_refnmsedec0: array[0..128] of integer;
|
|
_jpc_mqctxs: array[0..JPC_NUMCTXS] of integer;
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
|
|
function _malloc(size: Integer): Pointer; cdecl;
|
|
begin
|
|
result := allocmem(size);
|
|
end;
|
|
|
|
procedure _free(P: Pointer); cdecl;
|
|
begin
|
|
FreeMem(P);
|
|
end;
|
|
|
|
function _memset(P: Pointer; B: Byte; count: Integer): pointer; cdecl;
|
|
begin
|
|
FillChar(P^, count, B);
|
|
result := P;
|
|
end;
|
|
|
|
function _memcpy(dest, source: Pointer; count: Integer): pointer; cdecl;
|
|
begin
|
|
Move(source^, dest^, count);
|
|
result := dest;
|
|
end;
|
|
|
|
function __ftol: integer;
|
|
var
|
|
f: double;
|
|
begin
|
|
asm
|
|
lea eax, f // BC++ passes floats on the FPU stack
|
|
fstp qword ptr [eax] // Delphi passes floats on the CPU stack
|
|
end;
|
|
if f > 2147483647.0 then
|
|
f := 2147483647.0;
|
|
if f < -2147483648.0 then
|
|
f := 2147483648.0;
|
|
result := integer(Trunc(f));
|
|
end;
|
|
|
|
procedure __assert(__cond: PAnsiChar; __file: PAnsiChar; __line: integer); cdecl;
|
|
begin
|
|
end;
|
|
|
|
procedure _abort; cdecl;
|
|
begin
|
|
end;
|
|
|
|
procedure _iejdebug(p: PAnsiChar); cdecl;
|
|
begin
|
|
//
|
|
//outputdebugstring(p);
|
|
end;
|
|
|
|
function _memmove(dest, source: Pointer; count: Integer): pointer; cdecl;
|
|
begin
|
|
Move(source^, dest^, count);
|
|
result := dest;
|
|
end;
|
|
|
|
function _strlen(str: PAnsiChar): integer; cdecl;
|
|
begin
|
|
result := IEStrLen(str);
|
|
end;
|
|
|
|
function _realloc(block: pointer; size: integer): pointer; cdecl;
|
|
begin
|
|
reallocmem(block, size);
|
|
result := block;
|
|
end;
|
|
|
|
function _fscanf(f: pointer; format: PAnsiChar): integer; cdecl;
|
|
begin
|
|
result := 0;
|
|
end;
|
|
|
|
// not used in Jasper
|
|
procedure _unlink; cdecl;
|
|
begin
|
|
end;
|
|
|
|
// not used in Jasper
|
|
procedure _setmode; cdecl;
|
|
begin
|
|
end;
|
|
|
|
// not used in Jasper
|
|
procedure _fputc; cdecl;
|
|
begin
|
|
end;
|
|
|
|
type
|
|
TIETmpStream = class(TMemoryStream)
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
constructor TIETmpStream.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
destructor TIETmPStream.Destroy;
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
function _open(path: PAnsiChar; access, mode: integer): integer; cdecl;
|
|
begin
|
|
if path = 'TEMPSTREAM' then
|
|
result := integer(TIETmpStream.Create)
|
|
else
|
|
result := integer(path);
|
|
end;
|
|
|
|
function _read(stream: integer; buf: pointer; len: integer): integer; cdecl;
|
|
var
|
|
st: TStream;
|
|
begin
|
|
st := TStream(pointer(stream));
|
|
result := st.Read(pbyte(buf)^, len);
|
|
end;
|
|
|
|
function _close(stream: integer): integer; cdecl;
|
|
var
|
|
st: tstream;
|
|
begin
|
|
result := 0;
|
|
st := TStream(pointer(stream));
|
|
if (st is TIETmpStream) then
|
|
begin
|
|
FreeAndNil(st);
|
|
end;
|
|
end;
|
|
|
|
function _write(stream: integer; buf: pointer; len: integer): integer; cdecl;
|
|
var
|
|
st: tstream;
|
|
begin
|
|
st := TStream(pointer(stream));
|
|
result := st.Write(pbyte(buf)^, len);
|
|
end;
|
|
|
|
function _lseek(stream: integer; offset: integer; fromwhere: integer): integer; cdecl;
|
|
var
|
|
st: tstream;
|
|
begin
|
|
st := TStream(pointer(stream));
|
|
case fromwhere of
|
|
0: // SEEK_SET
|
|
result := st.Seek(offset, soBeginning);
|
|
1: // SEEK_CUR
|
|
result := st.Seek(offset, soCurrent);
|
|
2: // SEEK_END
|
|
result := st.Seek(offset, soEnd);
|
|
else
|
|
result := -1;
|
|
end;
|
|
end;
|
|
|
|
// we suppose that s is not null
|
|
function _tmpnam(s: PAnsiChar): PAnsiChar; cdecl;
|
|
begin
|
|
result := s;
|
|
IEStrPCopy(s, 'TEMPSTREAM');
|
|
end;
|
|
|
|
// used only for stdio io
|
|
procedure _fread; cdecl;
|
|
begin
|
|
end;
|
|
|
|
// used only for stdio io
|
|
function _fwrite(buf: PAnsiChar; size, n: integer; fil: pointer): integer; cdecl;
|
|
begin
|
|
result := size * n;
|
|
end;
|
|
|
|
// used only for stdio io
|
|
procedure _fseek; cdecl;
|
|
begin
|
|
end;
|
|
|
|
// used only for stdio io
|
|
procedure _fclose; cdecl;
|
|
begin
|
|
end;
|
|
|
|
function _isspace(c: integer): integer; cdecl;
|
|
begin
|
|
result := integer(c <= 32);
|
|
end;
|
|
|
|
function _isalpha(c: integer): integer; cdecl;
|
|
begin
|
|
result := integer(((c >= 65) and (c <= 90)) or ((c >= 97) and (c <= 122)) or (c = 95));
|
|
end;
|
|
|
|
function _isdigit(c: integer): integer; cdecl;
|
|
begin
|
|
result := integer((c >= 48) and (c <= 57));
|
|
end;
|
|
|
|
function _atol(s: PAnsiChar): integer; cdecl;
|
|
begin
|
|
result := IEStrToIntDef(s, 0);
|
|
end;
|
|
|
|
function _strchr(s: PAnsiChar; c: integer): PAnsiChar; cdecl;
|
|
begin
|
|
result := IEStrScan(s, AnsiChar(c));
|
|
end;
|
|
|
|
function _atof(s: PAnsiChar): double; cdecl;
|
|
var
|
|
q: AnsiString;
|
|
p1: integer;
|
|
begin
|
|
q := AnsiString(s);
|
|
p1 := IEPos(' ', q);
|
|
if p1 = 0 then
|
|
p1 := length(q) + 1;
|
|
setlength(q, p1 - 1);
|
|
result := IEStrToFloatDefA(q, 0);
|
|
end;
|
|
|
|
function _sqrt(x: double): double; cdecl;
|
|
begin
|
|
result := sqrt(x);
|
|
end;
|
|
|
|
function _strrchr(s: PAnsiChar; c: integer): PAnsiChar; cdecl;
|
|
begin
|
|
result := IEStrRScan(s, AnsiChar(c));
|
|
end;
|
|
|
|
function _isprint(c: integer): integer; cdecl;
|
|
begin
|
|
result := integer(c > 31);
|
|
end;
|
|
|
|
function _strncpy(dest, src: PAnsiChar; maxlen: integer): PAnsiChar; cdecl;
|
|
begin
|
|
result := IEStrMove(dest, src, maxlen);
|
|
end;
|
|
|
|
procedure __llmul;
|
|
asm
|
|
push edx
|
|
push eax
|
|
mov eax, [esp+16]
|
|
mul dword ptr [esp]
|
|
mov ecx, eax
|
|
mov eax, [esp+4]
|
|
mul dword ptr [esp+12]
|
|
add ecx, eax
|
|
mov eax, [esp]
|
|
mul dword ptr [esp+12]
|
|
add edx, ecx
|
|
pop ecx
|
|
pop ecx
|
|
ret 8
|
|
end;
|
|
|
|
procedure __lldiv;
|
|
asm
|
|
push ebp
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
xor edi,edi
|
|
mov ebx,20[esp]
|
|
mov ecx,24[esp]
|
|
or ecx,ecx
|
|
jnz @__lldiv@slow_ldiv
|
|
or edx,edx
|
|
jz @__lldiv@quick_ldiv
|
|
or ebx,ebx
|
|
jz @__lldiv@quick_ldiv
|
|
@__lldiv@slow_ldiv:
|
|
or edx,edx
|
|
jns @__lldiv@onepos
|
|
neg edx
|
|
neg eax
|
|
sbb edx,0
|
|
or edi,1
|
|
@__lldiv@onepos:
|
|
or ecx,ecx
|
|
jns @__lldiv@positive
|
|
neg ecx
|
|
neg ebx
|
|
sbb ecx,0
|
|
xor edi,1
|
|
@__lldiv@positive:
|
|
mov ebp,ecx
|
|
mov ecx,64
|
|
push edi
|
|
xor edi,edi
|
|
xor esi,esi
|
|
@__lldiv@xloop:
|
|
shl eax,1
|
|
rcl edx,1
|
|
rcl esi,1
|
|
rcl edi,1
|
|
cmp edi,ebp
|
|
jb @__lldiv@nosub
|
|
ja @__lldiv@subtract
|
|
cmp esi,ebx
|
|
jb @__lldiv@nosub
|
|
@__lldiv@subtract:
|
|
sub esi,ebx
|
|
sbb edi,ebp
|
|
inc eax
|
|
@__lldiv@nosub:
|
|
loop @__lldiv@xloop
|
|
pop ebx
|
|
test ebx,1
|
|
jz @__lldiv@finish
|
|
neg edx
|
|
neg eax
|
|
sbb edx,0
|
|
@__lldiv@finish:
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
pop ebp
|
|
ret 8
|
|
@__lldiv@quick_ldiv:
|
|
div ebx
|
|
xor edx,edx
|
|
jmp @__lldiv@finish
|
|
end;
|
|
|
|
procedure jpc_seglist_remove; external;
|
|
procedure jpc_seg_destroy; external;
|
|
procedure jpc_seglist_insert; external;
|
|
procedure jpc_decode; external;
|
|
procedure jp2_decode; external;
|
|
procedure jp2_encode; external;
|
|
procedure jp2_validate; external;
|
|
procedure jpc_seg_alloc; external;
|
|
procedure jas_stream_puts; external;
|
|
|
|
{$L jp2_enc.obj}
|
|
{$L jpc_enc.obj}
|
|
{$L jpc_dec.obj}
|
|
{$L jpc_t1dec.obj}
|
|
{$L jpc_t1enc.obj}
|
|
{$L jpc_t2enc.obj}
|
|
{$L jpc_t2dec.obj}
|
|
{$L jpc_t2cod.obj}
|
|
{$L jpc_t1cod.obj}
|
|
{$L jpc_tsfb.obj}
|
|
{$L jpc_qmfb.obj}
|
|
{$L jpc_mct.obj}
|
|
{$L jpc_bs.obj}
|
|
{$L jas_getopt.obj}
|
|
{$L jp2_dec.obj}
|
|
{$L jas_init.obj}
|
|
{$L jpc_mqdec.obj}
|
|
{$L jpc_mqenc.obj}
|
|
{$L jpc_mqcod.obj}
|
|
{$L jas_tvp.obj}
|
|
{$L jp2_cod.obj}
|
|
{$L jas_image.obj}
|
|
{$L jpc_cs.obj}
|
|
{$L jas_seq.obj}
|
|
{$L jas_malloc.obj}
|
|
{$L jas_stream.obj}
|
|
{$L jas_string.obj}
|
|
{$L jas_version.obj}
|
|
{$L jpc_math.obj}
|
|
{$L jpc_util.obj}
|
|
{$L jpc_tagtree.obj}
|
|
{$L jas_debug.obj}
|
|
|
|
{$L xlibcj2.obj}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
type
|
|
|
|
IEJP2K_Image = pjas_image_t;
|
|
IEJP2K_Matrix = pjas_matrix_t;
|
|
IEJP2K_ComponentParamsList = array of jas_image_cmptparm_t;
|
|
|
|
procedure IEJP2K_initialize();
|
|
begin
|
|
jas_init();
|
|
end;
|
|
|
|
procedure IEJP2K_finalize();
|
|
begin
|
|
jas_image_clearfmts();
|
|
end;
|
|
|
|
function IEJP2K_imageCreate(stream: TStream): IEJP2K_Image; overload;
|
|
var
|
|
js: pjas_stream_t;
|
|
begin
|
|
js := jas_stream_fopen(pointer(stream), 'rb');
|
|
try
|
|
result := jas_image_decode(js, -1, nil);
|
|
finally
|
|
jas_stream_close(js);
|
|
end;
|
|
end;
|
|
|
|
function IEJP2K_imageCreate(numComponents: word; parameters: IEJP2K_ComponentParamsList; colorModel: integer): IEJP2K_Image; overload;
|
|
begin
|
|
result := jas_image_create(numComponents, @parameters[0], colorModel);
|
|
end;
|
|
|
|
procedure IEJP2K_imageDestroy(var image: IEJP2K_image);
|
|
begin
|
|
if image <> nil then
|
|
begin
|
|
jas_image_destroy(image);
|
|
image := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure IEJP2K_imageEncode(image: IEJP2K_image; stream: TStream; format: integer; options: string);
|
|
var
|
|
js: pjas_stream_t;
|
|
begin
|
|
js := jas_stream_fopen(pointer(Stream), 'w+b');
|
|
try
|
|
jas_image_encode(image, js, format, PAnsiChar(AnsiString(options)));
|
|
jas_stream_flush(js);
|
|
finally
|
|
jas_stream_close(js);
|
|
end;
|
|
end;
|
|
|
|
function IEJP2K_getImageWidth(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := iejas_image_width(image);
|
|
end;
|
|
|
|
function IEJP2K_getImageHeight(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := iejas_image_height(image);
|
|
end;
|
|
|
|
function IEJP2K_getColorSpace(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := iejas_image_colorspace(image);
|
|
end;
|
|
|
|
// note: component can be JAS_IMAGE_CT_RGB_R, etc... no need to call JAS_IMAGE_CT_COLOR
|
|
function IEJP2K_getComponentByType(image: IEJP2K_Image; component: integer): integer;
|
|
begin
|
|
result := jas_image_getcmptbytype(image, (component and $7FFF));
|
|
end;
|
|
|
|
// note: component can be JAS_IMAGE_CT_RGB_R, etc... no need to call JAS_IMAGE_CT_COLOR
|
|
procedure IEJP2K_setComponentType(image: IEJP2K_Image; index: integer; component: integer);
|
|
begin
|
|
iejas_image_setcmpttype(image, index, (component and $7FFF));
|
|
end;
|
|
|
|
function IEJP2K_getComponentPrecision(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmptprec(image, index);
|
|
end;
|
|
|
|
function IEJP2K_getNumComponents(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := iejas_image_numcmpts(image);
|
|
end;
|
|
|
|
function IEJP2K_getComponentHeight(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmptheight(image, index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentWidth(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmptwidth(image, index);
|
|
end;
|
|
|
|
function IEJP2K_matrixCreate(numRows: integer; numCols: integer): IEJP2K_Matrix;
|
|
begin
|
|
result := jas_matrix_create(numRows, numCols);
|
|
end;
|
|
|
|
procedure IEJP2K_matrixDestroy(var matrix: IEJP2K_Matrix);
|
|
begin
|
|
jas_matrix_destroy(matrix);
|
|
matrix := nil;
|
|
end;
|
|
|
|
function IEJP2K_matrixGetValue(matrix: IEJP2K_Matrix; i: integer; j: integer): integer;
|
|
begin
|
|
result := iejas_matrix_get(matrix, i, j);
|
|
end;
|
|
|
|
function IEJP2K_readComponent(image: IEJP2K_Image; index: word; x: integer; y: integer; width: integer; height: integer; data: IEJP2K_Matrix): integer;
|
|
begin
|
|
result := jas_image_readcmpt(image, index, x, y, width, height, data);
|
|
end;
|
|
|
|
function IEJP2K_getComponentTopLeftY(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmpttly(image, index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentTopLeftX(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmpttlx(image, index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentVStep(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmptvstep(image, index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentHStep(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := iejas_image_cmpthstep(image, index);
|
|
end;
|
|
|
|
function IEJP2K_createComponentParametersList(size: integer): IEJP2K_ComponentParamsList;
|
|
begin
|
|
SetLength(result, size);
|
|
end;
|
|
|
|
procedure IEJP2K_destroyComponentParametersList(var parameters: IEJP2K_ComponentParamsList);
|
|
begin
|
|
SetLength(parameters, 0);
|
|
end;
|
|
|
|
procedure IEJP2K_setComponentParameters(parameters: IEJP2K_ComponentParamsList; index: integer; tlx: dword; tly: dword; hstep: dword; vstep: dword; width: dword; height: dword; prec: word; sgnd: integer);
|
|
begin
|
|
parameters[index].tlx := tlx;
|
|
parameters[index].tly := tly;
|
|
parameters[index].hstep := hstep;
|
|
parameters[index].vstep := vstep;
|
|
parameters[index].width := width;
|
|
parameters[index].height := height;
|
|
parameters[index].prec := prec;
|
|
parameters[index].sgnd := sgnd;
|
|
end;
|
|
|
|
procedure IEJP2K_writeComponentSample(image: IEJP2K_Image; index: integer; x: integer; y: integer; v: dword);
|
|
begin
|
|
jas_image_writecmptsample(image, index, x, y, v);
|
|
end;
|
|
|
|
procedure IEJP2K_writeRowRGB8(image: IEJP2K_Image; width: integer; rowIndex: integer; bgr8Array: PRGB; alphaArray: pbyte; colors: integer);
|
|
var
|
|
x: integer;
|
|
mul: double;
|
|
begin
|
|
mul := colors / 255;
|
|
for x := 0 to width - 1 do
|
|
begin
|
|
with bgr8Array^ do
|
|
begin
|
|
IEJP2K_writeComponentSample(image, 0, x, rowIndex, trunc(r * mul));
|
|
IEJP2K_writeComponentSample(image, 1, x, rowIndex, trunc(g * mul));
|
|
IEJP2K_writeComponentSample(image, 2, x, rowIndex, trunc(b * mul));
|
|
end;
|
|
if alphaArray <> nil then
|
|
begin
|
|
IEJP2K_writeComponentSample(image, 3, x, rowIndex, trunc(alphaArray^ * mul));
|
|
inc(alphaArray);
|
|
end;
|
|
inc(bgr8Array);
|
|
end;
|
|
end;
|
|
|
|
procedure IEJP2K_readLinearBGR8(image: IEJP2K_Image; blueMatrix: IEJP2K_Matrix; greenMatrix: IEJP2K_Matrix; redMatrix: IEJP2K_Matrix; rowIndex: integer; bluePrec: integer; greenPrec: integer; redPrec: integer; destBGR8: pbyte; width: integer);
|
|
var
|
|
j: integer;
|
|
begin
|
|
for j := 0 to width - 1 do
|
|
begin
|
|
destBGR8^ := (IEJP2K_matrixGetValue(blueMatrix, rowIndex, j) shl (32 - bluePrec)) shr 24;
|
|
inc(destBGR8);
|
|
destBGR8^ := (IEJP2K_matrixGetValue(greenMatrix, rowIndex, j) shl (32 - greenPrec)) shr 24;
|
|
inc(destBGR8);
|
|
destBGR8^ := (IEJP2K_matrixGetValue(redMatrix, rowIndex, j) shl (32 - redPrec)) shr 24;
|
|
inc(destBGR8);
|
|
end;
|
|
end;
|
|
|
|
|
|
{$endif} // IEUSEDLLJPEG2000LIB
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// dynamic (DLL) Jasper library wrappers
|
|
|
|
{$ifdef IEUSEDLLJPEG2000LIB}
|
|
|
|
|
|
type
|
|
|
|
IEJP2K_Image = TIELibJP2KImage;
|
|
IEJP2K_Matrix = TIELibJP2KMatrix;
|
|
IEJP2K_ComponentParamsList = TIELibJP2KComponentParamsList;
|
|
|
|
|
|
procedure IEJP2K_initialize();
|
|
begin
|
|
if IELibAvailable() then
|
|
IELib.JP2KInitialize()
|
|
else
|
|
raise EIEJPEG2000Exception.Create(IERS_IEVISIONNOTFOUND);
|
|
end;
|
|
|
|
procedure IEJP2K_finalize();
|
|
begin
|
|
if IELibAvailable() then
|
|
IELib.JP2KFinalize();
|
|
end;
|
|
|
|
function IEJP2K_imageCreate(stream: TStream): IEJP2K_Image; overload;
|
|
begin
|
|
result := IELib.createJP2KImage(IELib.createCustomStream(TIEVCLStreamProvider.Create(stream))); // TIEVCLStreamProvider will be freed by IEJP2K_Image (that is TIELibJP2KImage)
|
|
end;
|
|
|
|
function IEJP2K_imageCreate(numComponents: word; parameters: IEJP2K_ComponentParamsList; colorModel: integer): IEJP2K_Image; overload;
|
|
begin
|
|
result := IELib.createJP2KImage(numComponents, parameters, colorModel);
|
|
end;
|
|
|
|
procedure IEJP2K_imageDestroy(var image: IEJP2K_image);
|
|
begin
|
|
image := nil;
|
|
end;
|
|
|
|
procedure IEJP2K_imageEncode(image: IEJP2K_image; stream: TStream; format: integer; options: string);
|
|
begin
|
|
image.encode(IELib.createCustomStream(TIEVCLStreamProvider.Create(stream)), format, PAnsiChar(AnsiString(options))); // TIEVCLStreamProvider will be freed by IEJP2K_Image (that is TIELibJP2KImage)
|
|
end;
|
|
|
|
function IEJP2K_getImageWidth(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := image.getWidth();
|
|
end;
|
|
|
|
function IEJP2K_getImageHeight(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := image.getHeight();
|
|
end;
|
|
|
|
function IEJP2K_getColorSpace(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := image.getColorSpace();
|
|
end;
|
|
|
|
// note: component can be JAS_IMAGE_CT_RGB_R, etc... no need to call JAS_IMAGE_CT_COLOR
|
|
function IEJP2K_getComponentByType(image: IEJP2K_Image; component: integer): integer;
|
|
begin
|
|
result := image.getComponentByType(component);
|
|
end;
|
|
|
|
// note: component can be JAS_IMAGE_CT_RGB_R, etc... no need to call JAS_IMAGE_CT_COLOR
|
|
procedure IEJP2K_setComponentType(image: IEJP2K_Image; index: integer; component: integer);
|
|
begin
|
|
image.setComponentType(index, component);
|
|
end;
|
|
|
|
function IEJP2K_getComponentPrecision(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentPrecision(index);
|
|
end;
|
|
|
|
function IEJP2K_getNumComponents(image: IEJP2K_Image): integer;
|
|
begin
|
|
result := image.getNumComponents();
|
|
end;
|
|
|
|
function IEJP2K_getComponentHeight(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentHeight(index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentWidth(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentWidth(index);
|
|
end;
|
|
|
|
function IEJP2K_matrixCreate(numRows: integer; numCols: integer): IEJP2K_Matrix;
|
|
begin
|
|
result := IELib.createJP2KMatrix(numRows, numCols);
|
|
end;
|
|
|
|
procedure IEJP2K_matrixDestroy(var matrix: IEJP2K_Matrix);
|
|
begin
|
|
matrix := nil;
|
|
end;
|
|
|
|
function IEJP2K_matrixGetValue(matrix: IEJP2K_Matrix; i: integer; j: integer): integer;
|
|
begin
|
|
result := matrix.getValue(i, j);
|
|
end;
|
|
|
|
function IEJP2K_readComponent(image: IEJP2K_Image; index: word; x: integer; y: integer; width: integer; height: integer; data: IEJP2K_Matrix): integer;
|
|
begin
|
|
result := image.readComponent(index, x, y, width, height, data);
|
|
end;
|
|
|
|
function IEJP2K_getComponentTopLeftY(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentTopLeftY(index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentTopLeftX(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentTopLeftX(index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentVStep(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentVStep(index);
|
|
end;
|
|
|
|
function IEJP2K_getComponentHStep(image: IEJP2K_Image; index: integer): integer;
|
|
begin
|
|
result := image.getComponentHStep(index);
|
|
end;
|
|
|
|
function IEJP2K_createComponentParametersList(size: integer): IEJP2K_ComponentParamsList;
|
|
begin
|
|
result := IELib.createJP2KComponentParamsList(size);
|
|
end;
|
|
|
|
procedure IEJP2K_destroyComponentParametersList(var parameters: IEJP2K_ComponentParamsList);
|
|
begin
|
|
parameters := nil;
|
|
end;
|
|
|
|
procedure IEJP2K_setComponentParameters(parameters: IEJP2K_ComponentParamsList; index: integer; tlx: dword; tly: dword; hstep: dword; vstep: dword; width: dword; height: dword; prec: word; sgnd: integer);
|
|
begin
|
|
parameters.assign(index, tlx, tly, hstep, vstep, width, height, prec, sgnd);
|
|
end;
|
|
|
|
procedure IEJP2K_writeComponentSample(image: IEJP2K_Image; index: integer; x: integer; y: integer; v: dword);
|
|
begin
|
|
image.writeComponentSample(index, x, y, v);
|
|
end;
|
|
|
|
procedure IEJP2K_writeRowRGB8(image: IEJP2K_Image; width: integer; rowIndex: integer; bgr8Array: PRGB; alphaArray: pbyte; colors: integer);
|
|
begin
|
|
image.writeRowRGB8(width, rowIndex, pbyte(bgr8Array), alphaArray, colors);
|
|
end;
|
|
|
|
procedure IEJP2K_readLinearBGR8(image: IEJP2K_Image; blueMatrix: IEJP2K_Matrix; greenMatrix: IEJP2K_Matrix; redMatrix: IEJP2K_Matrix; rowIndex: integer; bluePrec: integer; greenPrec: integer; redPrec: integer; destBGR8: pbyte; width: integer);
|
|
begin
|
|
image.readLinearBGR8(blueMatrix, greenMatrix, redMatrix, rowIndex, bluePrec, greenPrec, redPrec, destBGR8, width);
|
|
end;
|
|
|
|
|
|
{$endif}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
function vctocc(i, co, cs: integer): integer;
|
|
begin
|
|
result := (i - co) div cs;
|
|
end;
|
|
|
|
// return true if is a jp2 stream
|
|
function J2KTryStreamJP2(Stream: TStream): boolean;
|
|
var
|
|
base: int64;
|
|
dw1, dw2, dw3: dword;
|
|
begin
|
|
base := Stream.position;
|
|
result := false;
|
|
// try jp2 - try jp2 signature
|
|
Stream.read(dw1, 4); // LBox
|
|
Stream.read(dw2, 4); // TBox
|
|
Stream.read(dw3, 4); // DBox
|
|
dw1 := IESwapDWord(dw1);
|
|
dw2 := IESwapDWord(dw2);
|
|
dw3 := IESwapDWord(dw3);
|
|
if (dw1 = 12) and (dw2 = $6A502020) and (dw3 = $0D0A870A) then
|
|
result := true;
|
|
|
|
Stream.position := base;
|
|
end;
|
|
|
|
// return true if is a jpc or j2k stream
|
|
function J2KTryStreamJ2K(Stream: TStream): boolean;
|
|
var
|
|
base: int64;
|
|
w1, w2: word;
|
|
begin
|
|
base := Stream.position;
|
|
result := false;
|
|
// try j2k, jpc -SOC, SIZ
|
|
Stream.read(w1, 2); // SOC
|
|
Stream.read(w2, 2); // SIZ
|
|
w1 := IESwapWord(w1);
|
|
w2 := IESwapWord(w2);
|
|
if (w1 = $FF4F) and (w2 = $FF51) then
|
|
result := true;
|
|
|
|
Stream.position := base;
|
|
end;
|
|
|
|
|
|
var
|
|
CrToRedTable, CbToBlueTable, CrToGreenTable, CbToGreenTable: array[0..255] of Integer;
|
|
YCbCrCoefficients: array[0..2] of Single;
|
|
|
|
|
|
procedure CreateYCbCrLookup;
|
|
var
|
|
F1, F2, F3, F4: Single;
|
|
LumaRed,
|
|
LumaGreen,
|
|
LumaBlue: Single;
|
|
I: Integer;
|
|
Offset1: Integer;
|
|
begin
|
|
YCbCrCoefficients[0] := 0.299;
|
|
YCbCrCoefficients[1] := 0.587;
|
|
YCbCrCoefficients[2] := 0.114;
|
|
LumaRed := YCbCrCoefficients[0];
|
|
LumaGreen := YCbCrCoefficients[1];
|
|
LumaBlue := YCbCrCoefficients[2];
|
|
F1 := 2 - 2 * LumaRed;
|
|
F2 := LumaRed * F1 / LumaGreen;
|
|
F3 := 2 - 2 * LumaBlue;
|
|
F4 := LumaBlue * F3 / LumaGreen;
|
|
Offset1 := -128;
|
|
for I := 0 to 255 do
|
|
begin
|
|
CrToRedTable[I] := Round(F1 * Offset1);
|
|
CbToBlueTable[I] := Round(F3 * Offset1);
|
|
CrToGreenTable[I] := -Round(F2 * Offset1);
|
|
CbToGreenTable[I] := -Round(F4 * Offset1);
|
|
Inc(Offset1);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure J2KReadStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var xProgress: TProgressRec; Preview: boolean);
|
|
var
|
|
im: IEJP2K_Image;
|
|
numcmpts, numc: integer;
|
|
i, j, q: integer;
|
|
prow: pbyte;
|
|
image_width, image_height: integer;
|
|
cmp: array [0..10] of integer;
|
|
mt: array [0..10] of IEJP2K_Matrix;
|
|
v: array [0..3] of integer;
|
|
u: array [0..3] of double;
|
|
vi: integer;
|
|
arx0, ary0: pintegerarray;
|
|
arx1, ary1: pintegerarray;
|
|
arx2, ary2: pintegerarray;
|
|
isLinear: boolean;
|
|
bStream: TIEBufferedReadStream;
|
|
pb: pbyte;
|
|
pw: pword;
|
|
begin
|
|
IEInitialize_iej2000();
|
|
|
|
if (not J2KTryStreamJP2(Stream)) and (not J2KTryStreamJ2K(Stream)) then
|
|
begin
|
|
xProgress.Aborting^ := true;
|
|
exit;
|
|
end;
|
|
|
|
im := nil;
|
|
|
|
try
|
|
|
|
bStream := TIEBufferedReadStream.Create(Stream, 8192);
|
|
try
|
|
im := IEJP2K_imageCreate(bStream);
|
|
finally
|
|
bStream.Free();
|
|
end;
|
|
|
|
if im = nil then
|
|
begin
|
|
xProgress.Aborting^ := true;
|
|
exit;
|
|
end;
|
|
|
|
numcmpts := IEJP2K_getNumComponents(im); // samples per pixel
|
|
|
|
image_width := IEJP2K_getImageWidth(im);
|
|
image_height := IEJP2K_getImageHeight(im);
|
|
numc := 3;
|
|
IOParams.ImageCount := 1;
|
|
case IEJP2K_getColorSpace(im) of
|
|
IEJAS_IMAGE_CS_RGB:
|
|
begin
|
|
cmp[0] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_RGB_R);
|
|
if cmp[0] > 255 then
|
|
cmp[0] := 0;
|
|
cmp[1] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_RGB_G);
|
|
if cmp[1] > 255 then
|
|
cmp[1] := 1;
|
|
cmp[2] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_RGB_B);
|
|
if cmp[2] > 255 then
|
|
cmp[2] := 2;
|
|
|
|
// has alpha channel?
|
|
if numcmpts = 4 then
|
|
begin
|
|
cmp[3] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_OPACITY and $7FFF);
|
|
if cmp[3] > 255 then
|
|
cmp[3] := 3;
|
|
end;
|
|
|
|
IOParams.BitsPerSample := IEJP2K_getComponentPrecision(im, cmp[0]);
|
|
IOParams.SamplesPerPixel := 3;
|
|
end;
|
|
IEJAS_IMAGE_CS_YCBCR:
|
|
begin
|
|
cmp[0] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_YCBCR_Y);
|
|
if cmp[0] > 255 then
|
|
cmp[0] := 0;
|
|
cmp[1] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_YCBCR_CB);
|
|
if cmp[1] > 255 then
|
|
cmp[1] := 0;
|
|
cmp[2] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_YCBCR_CR);
|
|
if cmp[2] > 255 then
|
|
cmp[2] := 0;
|
|
IOParams.BitsPerSample := IEJP2K_getComponentPrecision(im, cmp[0]);
|
|
IOParams.SamplesPerPixel := 3;
|
|
end;
|
|
IEJAS_IMAGE_CS_GRAY:
|
|
begin
|
|
cmp[0] := IEJP2K_getComponentByType(im, IEJAS_IMAGE_CT_GRAY_Y);
|
|
if cmp[0] > 255 then
|
|
cmp[0] := 0;
|
|
IOParams.BitsPerSample := IEJP2K_getComponentPrecision(im, cmp[0]);
|
|
IOParams.SamplesPerPixel := 1;
|
|
numc := 1;
|
|
end;
|
|
else
|
|
begin
|
|
// unsupported color space
|
|
xProgress.Aborting^ := true;
|
|
IEJP2K_imageDestroy(im);
|
|
exit;
|
|
end;
|
|
end;
|
|
IOParams.DpiX := IEGlobalSettings().DefaultDPIX;
|
|
IOParams.DpiY := IEGlobalSettings().DefaultDPIY;
|
|
IOParams.FreeColorMap();
|
|
IOParams.Width := image_width;
|
|
IOParams.Height := image_height;
|
|
IOParams.OriginalWidth := image_width;
|
|
IOParams.OriginalHeight := image_height;
|
|
|
|
if not Preview then
|
|
begin
|
|
|
|
for q := 0 to high(mt) do
|
|
mt[q] := nil;
|
|
arx0 := nil;
|
|
ary0 := nil;
|
|
arx1 := nil;
|
|
ary1 := nil;
|
|
arx2 := nil;
|
|
ary2 := nil;
|
|
|
|
try
|
|
|
|
if numcmpts = 2 then
|
|
numcmpts := 1;
|
|
|
|
for q := 0 to numcmpts - 1 do
|
|
begin
|
|
mt[q] := IEJP2K_matrixCreate(IEJP2K_getComponentHeight(im, q), IEJP2K_getComponentWidth(im, q));
|
|
IEJP2K_readComponent(im, q, 0, 0, IEJP2K_getComponentWidth(im, q), IEJP2K_getComponentHeight(im, q), mt[q]);
|
|
end;
|
|
|
|
if Bitmap.Location <> ieTBitmap then
|
|
begin
|
|
// native pixel format
|
|
case IEJP2K_getColorSpace(im) of
|
|
IEJAS_IMAGE_CS_RGB:
|
|
begin
|
|
Bitmap.Allocate(image_width, image_height, ie24RGB);
|
|
end;
|
|
IEJAS_IMAGE_CS_YCBCR:
|
|
begin
|
|
Bitmap.Allocate(image_width, image_height, ie24RGB);
|
|
end;
|
|
IEJAS_IMAGE_CS_GRAY:
|
|
begin
|
|
if IOParams.BitsPerSample = 1 then
|
|
Bitmap.Allocate(image_width, image_height, ie1g)
|
|
else
|
|
if IOParams.BitsPerSample = 8 then
|
|
Bitmap.Allocate(image_width, image_height, ie8g)
|
|
else
|
|
if IOParams.BitsPerSample > 8 then
|
|
Bitmap.Allocate(image_width, image_height, ie16g)
|
|
else
|
|
Bitmap.Allocate(image_width, image_height, ie24RGB); // unsupported native
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// using TBitmap
|
|
if (IOParams.BitsPerSample = 1) and (IOParams.SamplesPerPixel = 1) then
|
|
Bitmap.Allocate(image_width, image_height, ie1g)
|
|
else
|
|
Bitmap.Allocate(image_width, image_height, ie24RGB);
|
|
end;
|
|
|
|
xProgress.per1 := 100 / image_height;
|
|
|
|
isLinear := true;
|
|
for q := 0 to imin(numc, numcmpts) - 1 do
|
|
begin
|
|
for i := 0 to image_height - 1 do
|
|
begin
|
|
if vctocc(i, IEJP2K_getComponentTopLeftY(im, cmp[q]), IEJP2K_getComponentVStep(im, cmp[q])) <> i then
|
|
begin
|
|
isLinear := false;
|
|
break;
|
|
end;
|
|
for j := 0 to image_width -1 do
|
|
begin
|
|
if vctocc(j, IEJP2K_getComponentTopLeftX(im, cmp[0]), IEJP2K_getComponentHStep(im, cmp[0])) <> j then
|
|
begin
|
|
isLinear := false;
|
|
break;
|
|
end;
|
|
end;
|
|
if not isLinear then
|
|
break;
|
|
end;
|
|
if not isLinear then
|
|
break;
|
|
end;
|
|
|
|
if (not isLinear) and (numcmpts = 3) then
|
|
begin
|
|
getmem(arx0, sizeof(integer) * image_width);
|
|
getmem(ary0, sizeof(integer) * image_height);
|
|
getmem(arx1, sizeof(integer) * image_width);
|
|
getmem(ary1, sizeof(integer) * image_height);
|
|
getmem(arx2, sizeof(integer) * image_width);
|
|
getmem(ary2, sizeof(integer) * image_height);
|
|
for i := 0 to image_height - 1 do
|
|
begin
|
|
ary0[i] := vctocc(i, IEJP2K_getComponentTopLeftY(im, cmp[0]), IEJP2K_getComponentVStep(im, cmp[0]));
|
|
if (ary0[i] < 0) or (ary0[i] >= IEJP2K_getComponentHeight(im, cmp[0])) then
|
|
ary0[i] := 0;
|
|
|
|
ary1[i] := vctocc(i, IEJP2K_getComponentTopLeftY(im, cmp[1]), IEJP2K_getComponentVStep(im, cmp[1]));
|
|
if (ary1[i] < 0) or (ary1[i] >= IEJP2K_getComponentHeight(im, cmp[1])) then
|
|
ary1[i] := 0;
|
|
|
|
ary2[i] := vctocc(i, IEJP2K_getComponentTopLeftY(im, cmp[2]), IEJP2K_getComponentVStep(im, cmp[2]));
|
|
if (ary2[i] < 0) or (ary2[i] >= IEJP2K_getComponentHeight(im, cmp[2])) then
|
|
ary2[i] := 0;
|
|
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
arx0[j] := vctocc(j, IEJP2K_getComponentTopLeftX(im, cmp[0]), IEJP2K_getComponentHStep(im, cmp[0]));
|
|
if (arx0[j] < 0) or (arx0[j] >= IEJP2K_getComponentWidth(im, cmp[0])) then
|
|
arx0[j] := 0;
|
|
|
|
arx1[j] := vctocc(j, IEJP2K_getComponentTopLeftX(im, cmp[1]), IEJP2K_getComponentHStep(im, cmp[1]));
|
|
if (arx1[j] < 0) or (arx1[j] >= IEJP2K_getComponentWidth(im, cmp[1])) then
|
|
arx1[j] := 0;
|
|
|
|
arx2[j] := vctocc(j, IEJP2K_getComponentTopLeftX(im, cmp[2]), IEJP2K_getComponentHStep(im, cmp[2]));
|
|
if (arx2[j] < 0) or (arx2[j] >= IEJP2K_getComponentWidth(im, cmp[2])) then
|
|
arx2[j] := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (not isLinear) and (numcmpts = 1) then
|
|
begin
|
|
getmem(arx0, sizeof(integer) * image_width);
|
|
getmem(ary0, sizeof(integer) * image_height);
|
|
for i := 0 to image_height - 1 do
|
|
begin
|
|
ary0[i] := vctocc(i, IEJP2K_getComponentTopLeftY(im, cmp[0]), IEJP2K_getComponentVStep(im, cmp[0]));
|
|
if (ary0[i] < 0) or (ary0[i] >= IEJP2K_getComponentHeight(im, cmp[0])) then
|
|
ary0[i] := 0;
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
arx0[j] := vctocc(j, IEJP2K_getComponentTopLeftX(im, cmp[0]), IEJP2K_getComponentHStep(im, cmp[0]));
|
|
if (arx0[j] < 0) or (arx0[j] >= IEJP2K_getComponentWidth(im, cmp[0])) then
|
|
arx0[j] := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if numcmpts = 3 then
|
|
begin
|
|
for i := 0 to image_height - 1 do
|
|
begin
|
|
prow := bitmap.ScanLine[i];
|
|
case IEJP2K_getColorSpace(im) of
|
|
IEJAS_IMAGE_CS_RGB:
|
|
begin
|
|
if isLinear then
|
|
begin
|
|
IEJP2K_readLinearBGR8(im, mt[cmp[2]], mt[cmp[1]], mt[cmp[0]], i, IEJP2K_getComponentPrecision(im, cmp[2]), IEJP2K_getComponentPrecision(im, cmp[1]), IEJP2K_getComponentPrecision(im, cmp[0]), prow, image_width);
|
|
end
|
|
else
|
|
begin
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
prow^ := (IEJP2K_matrixGetValue(mt[cmp[2]], ary2[i], arx2[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[2]))) shr 24;
|
|
inc(prow);
|
|
prow^ := (IEJP2K_matrixGetValue(mt[cmp[1]], ary1[i], arx1[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[1]))) shr 24;
|
|
inc(prow);
|
|
prow^ := (IEJP2K_matrixGetValue(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24;
|
|
inc(prow);
|
|
end;
|
|
end;
|
|
end;
|
|
IEJAS_IMAGE_CS_YCBCR:
|
|
begin
|
|
if isLinear then
|
|
begin
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
v[0] := (IEJP2K_matrixGetValue(mt[cmp[0]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24;
|
|
v[1] := (IEJP2K_matrixGetValue(mt[cmp[1]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[1]))) shr 24;
|
|
v[2] := (IEJP2K_matrixGetValue(mt[cmp[2]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[2]))) shr 24;
|
|
u[0] := blimit(v[0] + CrToRedTable[v[2]]);
|
|
u[1] := blimit(v[0] + CbToGreenTable[v[1]] + CrToGreentable[v[2]]);
|
|
u[2] := blimit(v[0] + CbToBlueTable[v[1]]);
|
|
v[0] := trunc(u[0]);
|
|
v[1] := trunc(u[1]);
|
|
v[2] := trunc(u[2]);
|
|
prow^ := blimit(v[2]);
|
|
inc(prow);
|
|
prow^ := blimit(v[1]);
|
|
inc(prow);
|
|
prow^ := blimit(v[0]);
|
|
inc(prow);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
v[0] := (IEJP2K_matrixGetValue(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24;
|
|
v[1] := (IEJP2K_matrixGetValue(mt[cmp[1]], ary1[i], arx1[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[1]))) shr 24;
|
|
v[2] := (IEJP2K_matrixGetValue(mt[cmp[2]], ary2[i], arx2[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[2]))) shr 24;
|
|
u[0] := blimit(v[0] + CrToRedTable[v[2]]);
|
|
u[1] := blimit(v[0] + CbToGreenTable[v[1]] + CrToGreentable[v[2]]);
|
|
u[2] := blimit(v[0] + CbToBlueTable[v[1]]);
|
|
v[0] := trunc(u[0]);
|
|
v[1] := trunc(u[1]);
|
|
v[2] := trunc(u[2]);
|
|
prow^ := blimit(v[2]);
|
|
inc(prow);
|
|
prow^ := blimit(v[1]);
|
|
inc(prow);
|
|
prow^ := blimit(v[0]);
|
|
inc(prow);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * (i)));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end
|
|
|
|
else
|
|
if (numcmpts = 4) and isLinear then
|
|
begin
|
|
// alpha channel currently not supported (this is discarded now)
|
|
for i := 0 to image_height - 1 do
|
|
begin
|
|
prow := bitmap.ScanLine[i];
|
|
case IEJP2K_getColorSpace(im) of
|
|
IEJAS_IMAGE_CS_RGB:
|
|
begin
|
|
IEJP2K_readLinearBGR8(im, mt[cmp[2]], mt[cmp[1]], mt[cmp[0]], i, IEJP2K_getComponentPrecision(im, cmp[2]), IEJP2K_getComponentPrecision(im, cmp[1]), IEJP2K_getComponentPrecision(im, cmp[0]), prow, image_width);
|
|
end;
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * (i)));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end
|
|
|
|
else
|
|
if (numcmpts = 1) or (IEJP2K_getColorSpace(im) = IEJAS_IMAGE_CS_GRAY) then
|
|
begin
|
|
for i := 0 to image_height - 1 do
|
|
begin
|
|
case Bitmap.PixelFormat of
|
|
ie1g:
|
|
begin
|
|
prow := bitmap.ScanLine[i];
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
if isLinear then
|
|
vi := (IEJP2K_matrixGetValue(mt[cmp[0]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24
|
|
else
|
|
vi := (IEJP2K_matrixGetValue(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24;
|
|
_SetPixelbw(pbyte(prow), j, vi);
|
|
end;
|
|
end;
|
|
ie8g:
|
|
begin
|
|
pb := bitmap.ScanLine[i];
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
if isLinear then
|
|
pb^ := (IEJP2K_matrixGetValue(mt[cmp[0]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24
|
|
else
|
|
pb^ := (IEJP2K_matrixGetValue(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24;
|
|
inc(pb);
|
|
end;
|
|
end;
|
|
ie16g:
|
|
begin
|
|
pw := bitmap.ScanLine[i];
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
if isLinear then
|
|
pw^ := (IEJP2K_matrixGetValue(mt[cmp[0]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 16
|
|
else
|
|
pw^ := (IEJP2K_matrixGetValue(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 16;
|
|
inc(pw);
|
|
end;
|
|
end;
|
|
ie24RGB:
|
|
begin
|
|
prow := bitmap.ScanLine[i];
|
|
for j := 0 to image_width - 1 do
|
|
begin
|
|
if isLinear then
|
|
vi := (IEJP2K_matrixGetValue(mt[cmp[0]], i, j) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24
|
|
else
|
|
vi := (IEJP2K_matrixGetValue(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - IEJP2K_getComponentPrecision(im, cmp[0]))) shr 24;
|
|
prow^ := vi;
|
|
inc(prow);
|
|
prow^ := vi;
|
|
inc(prow);
|
|
prow^ := vi;
|
|
inc(prow);
|
|
end;
|
|
end;
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * (i)));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
|
|
for q := 0 to high(mt) do
|
|
if mt[q] <> nil then
|
|
IEJP2K_matrixDestroy(mt[q]);
|
|
|
|
// free even when they are "nil"
|
|
freemem(arx0);
|
|
freemem(ary0);
|
|
freemem(arx1);
|
|
freemem(ary1);
|
|
freemem(arx2);
|
|
freemem(ary2);
|
|
end;
|
|
|
|
end; // not preview
|
|
|
|
finally
|
|
IEJP2K_imageDestroy(im);
|
|
end;
|
|
end;
|
|
|
|
|
|
// fmt can be JAS_IMAGE_CM_GRAY(1), JAS_IMAGE_CM_RGB(2), JAS_IMAGE_CM_YCC(3)
|
|
// format: 0=jp2 1=j2k/jpc
|
|
procedure J2KWriteStream(Stream: TStream; Bitmap: TIEBitmap; var IOParams: TIOParams; var xProgress: TProgressRec; format: integer);
|
|
var
|
|
im: IEJP2K_Image;
|
|
cmptparams: IEJP2K_ComponentParamsList;
|
|
outopts: string;
|
|
ww, hh, y, x, vv, colors: integer;
|
|
row: PRGB;
|
|
pb: pbyte;
|
|
pw: pword;
|
|
NullProgress: TProgressRec;
|
|
a: pbyte;
|
|
HasAlpha: boolean;
|
|
bStream: TIEBufferedWriteStream;
|
|
RedToGrayCoef, GreenToGrayCoef, BlueToGrayCoef: integer;
|
|
begin
|
|
IEInitialize_iej2000();
|
|
|
|
NullProgress := NullProgressRec( xProgress.Aborting, False );
|
|
im := nil;
|
|
|
|
ww := Bitmap.Width;
|
|
hh := Bitmap.Height;
|
|
|
|
case Bitmap.PixelFormat of
|
|
ie1g:
|
|
begin
|
|
IOParams.BitsPerSample := 1;
|
|
IOParams.J2000_ColorSpace := ioJ2000_GRAYLEV;
|
|
end;
|
|
ie8g:
|
|
begin
|
|
IOParams.BitsPerSample := 8;
|
|
IOParams.J2000_ColorSpace := ioJ2000_GRAYLEV;
|
|
end;
|
|
ie16g:
|
|
begin
|
|
IOParams.BitsPerSample := 16;
|
|
IOParams.J2000_ColorSpace := ioJ2000_GRAYLEV;
|
|
end;
|
|
end;
|
|
|
|
colors := (1 shl IOParams.BitsPerSample) - 1;
|
|
|
|
if hh = 0 then
|
|
xProgress.per1 := 0
|
|
else
|
|
xProgress.per1 := 100 / hh;
|
|
xProgress.val := 0;
|
|
|
|
cmptparams := nil;
|
|
|
|
case IOParams.J2000_ColorSpace of
|
|
ioJ2000_GRAYLEV:
|
|
begin
|
|
// gray scale or black/white
|
|
cmptparams := IEJP2K_createComponentParametersList(1);
|
|
IEJP2K_setComponentParameters(cmptparams, 0, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
|
|
im := IEJP2K_imageCreate(1, cmptparams, IEJAS_IMAGE_CS_GRAY);
|
|
|
|
IEJP2K_setComponentType(im, 0, IEJAS_IMAGE_CT_GRAY_Y);
|
|
|
|
if bitmap.PixelFormat = ie24RGB then
|
|
begin
|
|
// gray scale
|
|
RedToGrayCoef := IEGlobalSettings().RedToGrayCoef;
|
|
GreenToGrayCoef := IEGlobalSettings().GreenToGrayCoef;
|
|
BlueToGrayCoef := IEGlobalSettings().BlueToGrayCoef;
|
|
for y := 0 to hh - 1 do
|
|
begin
|
|
row := Bitmap.Scanline[y];
|
|
for x := 0 to ww - 1 do
|
|
begin
|
|
with row^ do
|
|
begin
|
|
vv := trunc((((r * RedToGrayCoef + g * GreenToGrayCoef + b * BlueToGrayCoef) div 100) / 255) * colors);
|
|
IEJP2K_writeComponentSample(im, 0, x, y, vv);
|
|
end;
|
|
inc(row);
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * y));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end
|
|
else
|
|
if Bitmap.PixelFormat = ie8g then
|
|
begin
|
|
// native 8 bit gray scale
|
|
for y := 0 to hh - 1 do
|
|
begin
|
|
pb := Bitmap.Scanline[y];
|
|
for x := 0 to ww - 1 do
|
|
begin
|
|
IEJP2K_writeComponentSample(im, 0, x, y, pb^);
|
|
inc(pb);
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * y));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end
|
|
else
|
|
if Bitmap.PixelFormat = ie16g then
|
|
begin
|
|
// native 16 bit gray scale
|
|
for y := 0 to hh - 1 do
|
|
begin
|
|
pw := Bitmap.Scanline[y];
|
|
for x := 0 to ww - 1 do
|
|
begin
|
|
IEJP2K_writeComponentSample(im, 0, x, y, pw^);
|
|
inc(pw);
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * y));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// black/white
|
|
for y := 0 to hh - 1 do
|
|
begin
|
|
row := Bitmap.Scanline[y];
|
|
for x := 0 to ww - 1 do
|
|
begin
|
|
if _GetPixelbw(pbyte(row), x) <> 0 then
|
|
IEJP2K_writeComponentSample(im, 0, x, y, 1)
|
|
else
|
|
IEJP2K_writeComponentSample(im, 0, x, y, 0);
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * y));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
ioJ2000_YCbCr, // for now YCC=RGB
|
|
ioJ2000_RGB:
|
|
begin
|
|
HasAlpha := Bitmap.HasAlphaChannel and not Bitmap.AlphaChannel.Full;
|
|
|
|
if HasAlpha then
|
|
begin
|
|
cmptparams := IEJP2K_createComponentParametersList(4);
|
|
IEJP2K_setComponentParameters(cmptparams, 0, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
IEJP2K_setComponentParameters(cmptparams, 1, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
IEJP2K_setComponentParameters(cmptparams, 2, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
IEJP2K_setComponentParameters(cmptparams, 3, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
im := IEJP2K_imageCreate(4, cmptparams, IEJAS_IMAGE_CS_RGB);
|
|
end
|
|
else
|
|
begin
|
|
cmptparams := IEJP2K_createComponentParametersList(3);
|
|
IEJP2K_setComponentParameters(cmptparams, 0, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
IEJP2K_setComponentParameters(cmptparams, 1, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
IEJP2K_setComponentParameters(cmptparams, 2, 0, 0, 1, 1, ww, hh, IOParams.BitsPerSample, 0);
|
|
im := IEJP2K_imageCreate(3, cmptparams, IEJAS_IMAGE_CS_RGB);
|
|
end;
|
|
|
|
IEJP2K_setComponentType(im, 0, IEJAS_IMAGE_CT_RGB_R);
|
|
IEJP2K_setComponentType(im, 1, IEJAS_IMAGE_CT_RGB_G);
|
|
IEJP2K_setComponentType(im, 2, IEJAS_IMAGE_CT_RGB_B);
|
|
if HasAlpha then
|
|
IEJP2K_setComponentType(im, 3, IEJAS_IMAGE_CT_OPACITY);
|
|
|
|
a := nil;
|
|
for y := 0 to hh - 1 do
|
|
begin
|
|
row := Bitmap.Scanline[y];
|
|
if HasAlpha then
|
|
a := Bitmap.AlphaChannel.ScanLine[y];
|
|
IEJP2K_writeRowRGB8(im, ww, y, row, a, colors);
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1 * y));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end;
|
|
// Attention: YCbCr is not supported for writing. Unfortunately only Y channel is loaded.
|
|
(*
|
|
ioJ2000_YCbCr:
|
|
begin
|
|
im := jas_image_create0();
|
|
iejas_image_setcolorspace(im, JAS_IMAGE_CS_YCBCR);
|
|
jas_image_addcmpt(im, 0, cmptparams);
|
|
jas_image_addcmpt(im, 1, cmptparams);
|
|
jas_image_addcmpt(im, 2, cmptparams);
|
|
IEJP2K_setComponentType(im, 0, (JAS_IMAGE_CT_YCBCR_Y));
|
|
IEJP2K_setComponentType(im, 1, (JAS_IMAGE_CT_YCBCR_CB));
|
|
IEJP2K_setComponentType(im, 2, (JAS_IMAGE_CT_YCBCR_CR));
|
|
for y := 0 to hh-1 do begin
|
|
row := Bitmap.Scanline[y];
|
|
for x := 0 to ww-1 do begin
|
|
with row^ do begin
|
|
yy := trunc( 0.29900 * R + 0.58700 * G + 0.11400 * B );
|
|
cb := trunc( -0.16874 * R - 0.33126 * G + 0.50000 * B + 128 );
|
|
Cr := trunc( 0.50000 * R - 0.41869 * G - 0.08131 * B + 128 );
|
|
IEJP2K_writeComponentSample(im, 0, x, y, yy);
|
|
IEJP2K_writeComponentSample(im, 1, x, y, cb);
|
|
IEJP2K_writeComponentSample(im, 2, x, y, cr);
|
|
end;
|
|
inc(row);
|
|
end;
|
|
// OnProgress
|
|
with xProgress do
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Sender, trunc(per1*y));
|
|
if xProgress.Aborting^ then
|
|
break;
|
|
end;
|
|
end;
|
|
//*)
|
|
end;
|
|
|
|
outopts := 'rate=' + IEFloatToStrS(IOParams.J2000_Rate);
|
|
if IOParams.J2000_ScalableBy = ioJ2000_Rate then
|
|
outopts := outopts + ' prg=lrcp'
|
|
else
|
|
if IOParams.J2000_ScalableBy = ioJ2000_Resolution then
|
|
outopts := outopts + ' prg=rlcp';
|
|
|
|
bStream := TIEBufferedWriteStream.Create(Stream, 8192);
|
|
IEJP2K_imageEncode(im, bStream, format, outopts);
|
|
bStream.Free();
|
|
|
|
IEJP2K_imageDestroy(im);
|
|
|
|
IEJP2K_destroyComponentParametersList(cmptparams);
|
|
end;
|
|
|
|
|
|
var
|
|
iej2000Init: boolean = false;
|
|
|
|
procedure IEInitialize_iej2000();
|
|
begin
|
|
if not iej2000Init then
|
|
begin
|
|
CreateYCbCrLookup();
|
|
IEJP2K_initialize();
|
|
iej2000Init := true;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure IEFinalize_iej2000();
|
|
begin
|
|
if iej2000Init then
|
|
IEJP2K_finalize();
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{$else} // IEINCLUDEJPEG2000
|
|
|
|
interface
|
|
implementation
|
|
|
|
{$endif} // IEINCLUDEJPEG2000
|
|
|
|
|
|
|
|
end.
|
|
|