📄 iej2000.pas
字号:
ReadBox(stream);
Stream.position:=lpos;
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: TIOParamsVals; var xProgress: TProgressRec; Preview: boolean);
var
js: pjas_stream_t;
im: pjas_image_t;
numcmpts, numc: integer;
color: boolean;
i, j, k, q, x, y: integer;
prow: pbyte;
depth: integer;
colormodel: integer;
image_width, image_height: integer;
cmp: array[0..10] of integer;
mt: array[0..10] of pjas_matrix_t;
v: array[0..3] of integer;
u: array[0..3] of double;
arx0, ary0: pintegerarray;
arx1, ary1: pintegerarray;
arx2, ary2: pintegerarray;
begin
//jas_setdbglevel(1000);
if (not J2KTryStreamJP2(Stream)) and (not J2KTryStreamJ2K(Stream)) then
begin
xProgress.Aborting^ := true;
exit;
end;
js := jas_stream_fopen(pointer(Stream), 'rb');
im := jas_image_decode(js, -1, nil);
jas_stream_close(js);
if im = nil then
begin
xProgress.Aborting^ := true;
exit;
end;
image_width := iejas_image_width(im);
image_height := iejas_image_height(im);
color := true;
numc := 3;
case iejas_image_colorspace(im) of
JAS_IMAGE_CS_RGB:
begin
cmp[0] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R));
if cmp[0] > 255 then
cmp[0] := 0;
cmp[1] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G));
if cmp[1] > 255 then
cmp[1] := 1;
cmp[2] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B));
if cmp[2] > 255 then
cmp[2] := 2;
IOParams.BitsPerSample := iejas_image_cmptprec(im, cmp[0]);
IOParams.SamplesPerPixel := 3;
end;
JAS_IMAGE_CS_YCBCR:
begin
cmp[0] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_Y));
if cmp[0] > 255 then
cmp[0] := 0;
cmp[1] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CB));
if cmp[1] > 255 then
cmp[1] := 0;
cmp[2] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CR));
if cmp[2] > 255 then
cmp[2] := 0;
IOParams.BitsPerSample := iejas_image_cmptprec(im, cmp[0]);
IOParams.SamplesPerPixel := 3;
end;
JAS_IMAGE_CS_GRAY:
begin
cmp[0] := jas_image_getcmptbytype(im, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y));
if cmp[0] > 255 then
cmp[0] := 0;
IOParams.BitsPerSample := iejas_image_cmptprec(im, cmp[0]);
IOParams.SamplesPerPixel := 1;
numc := 1;
color := false;
end;
else
begin
// unsupported color space
xProgress.Aborting^ := true;
jas_image_destroy(im);
exit;
end;
end;
IOParams.DpiX := gDefaultDPIX;
IOParams.DpiY := gDefaultDPIY;
if IOParams.ColorMap <> nil then
begin
freemem(IOParams.ColorMap);
IOParams.fColorMap := nil;
IOParams.fColorMapCount := 0;
end;
IOParams.Width := image_width;
IOParams.Height := image_height;
if not Preview then
begin
numcmpts := iejas_image_numcmpts(im); // samples per pixel
for q := 0 to numcmpts - 1 do
begin
mt[q] := jas_matrix_create(iejas_image_cmptheight(im, q), iejas_image_cmptwidth(im, q));
jas_image_readcmpt(im, q, 0, 0, iejas_image_cmptwidth(im, q), iejas_image_cmptheight(im, q), mt[q]);
end;
(*
Bitmap.Width := 1;
Bitmap.Height := 1;
if (IOParams.BitsPerSample = 1) and (IOParams.SamplesPerPixel = 1) then
bitmap.pixelformat := ie1g
else
bitmap.pixelformat := ie24RGB;
bitmap.height := image_height;
bitmap.width := image_width;
*)
if (IOParams.BitsPerSample = 1) and (IOParams.SamplesPerPixel = 1) then
bitmap.Allocate(image_width,image_height,ie1g)
else
bitmap.Allocate(image_width,image_height,ie24RGB);
xProgress.per1 := 100 / image_height;
//
arx0 := nil;
ary0 := nil;
arx1 := nil;
ary1 := nil;
arx2 := nil;
ary2 := nil;
//
if numc = 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, iejas_image_cmpttly(im, cmp[0]), iejas_image_cmptvstep(im, cmp[0]));
if (ary0[i] < 0) or (ary0[i] >= iejas_image_cmptheight(im, cmp[0])) then
ary0[i] := 0;
ary1[i] := vctocc(i, iejas_image_cmpttly(im, cmp[1]), iejas_image_cmptvstep(im, cmp[1]));
if (ary1[i] < 0) or (ary1[i] >= iejas_image_cmptheight(im, cmp[1])) then
ary1[i] := 0;
ary2[i] := vctocc(i, iejas_image_cmpttly(im, cmp[2]), iejas_image_cmptvstep(im, cmp[2]));
if (ary2[i] < 0) or (ary2[i] >= iejas_image_cmptheight(im, cmp[2])) then
ary0[i] := 0;
for j := 0 to image_width - 1 do
begin
arx0[j] := vctocc(j, iejas_image_cmpttlx(im, cmp[0]), iejas_image_cmpthstep(im, cmp[0]));
if (arx0[j] < 0) or (arx0[j] >= iejas_image_cmptwidth(im, cmp[0])) then
arx0[j] := 0;
arx1[j] := vctocc(j, iejas_image_cmpttlx(im, cmp[1]), iejas_image_cmpthstep(im, cmp[1]));
if (arx1[j] < 0) or (arx1[j] >= iejas_image_cmptwidth(im, cmp[1])) then
arx1[j] := 0;
arx2[j] := vctocc(j, iejas_image_cmpttlx(im, cmp[2]), iejas_image_cmpthstep(im, cmp[2]));
if (arx2[j] < 0) or (arx2[j] >= iejas_image_cmptwidth(im, cmp[2])) then
arx2[j] := 0;
end;
end;
end;
if numc = 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, iejas_image_cmpttly(im, cmp[0]), iejas_image_cmptvstep(im, cmp[0]));
if (ary0[i] < 0) or (ary0[i] >= iejas_image_cmptheight(im, cmp[0])) then
ary0[i] := 0;
for j := 0 to image_width - 1 do
begin
arx0[j] := vctocc(j, iejas_image_cmpttlx(im, cmp[0]), iejas_image_cmpthstep(im, cmp[0]));
if (arx0[j] < 0) or (arx0[j] >= iejas_image_cmptwidth(im, cmp[0])) then
arx0[j] := 0;
end;
end;
end;
//
if color then
begin
for i := 0 to image_height - 1 do
begin
prow := bitmap.scanline[i];
for j := 0 to image_width - 1 do
begin
v[0] := (iejas_matrix_get(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - iejas_image_cmptprec(im, cmp[0]))) shr 24;
v[1] := (iejas_matrix_get(mt[cmp[1]], ary1[i], arx1[j]) shl (32 - iejas_image_cmptprec(im, cmp[1]))) shr 24;
v[2] := (iejas_matrix_get(mt[cmp[2]], ary2[i], arx2[j]) shl (32 - iejas_image_cmptprec(im, cmp[2]))) shr 24;
case iejas_image_colorspace(im) of
JAS_IMAGE_CS_RGB:
begin
prow^ := v[2];
inc(prow);
prow^ := v[1];
inc(prow);
prow^ := v[0];
inc(prow);
end;
JAS_IMAGE_CS_YCBCR:
begin
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;
// OnProgress
with xProgress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * (i)));
if xProgress.Aborting^ then
break;
end;
end
else
begin
for i := 0 to image_height - 1 do
begin
prow := bitmap.scanline[i];
for j := 0 to image_width - 1 do
begin
v[0] := (iejas_matrix_get(mt[cmp[0]], ary0[i], arx0[j]) shl (32 - iejas_image_cmptprec(im, cmp[0]))) shr 24;
v[1] := v[0];
v[2] := v[0];
if bitmap.pixelformat = ie24RGB then
begin
// color or gray scale
prow^ := v[2];
inc(prow);
prow^ := v[1];
inc(prow);
prow^ := v[0];
inc(prow);
end
else
begin
// black/white
_SetPixelbw(pbyte(prow), j, v[0]);
end;
end;
// OnProgress
with xProgress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * (i)));
if xProgress.Aborting^ then
break;
end;
end;
//
for q := 0 to numcmpts - 1 do
jas_matrix_destroy(mt[q]);
freemem(arx0);
freemem(ary0);
if numc = 3 then
begin
freemem(arx1);
freemem(ary1);
freemem(arx2);
freemem(ary2);
end;
end; // not preview
jas_image_destroy(im);
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: TIOParamsVals; var xProgress: TProgressRec; format: integer);
var
js: pjas_stream_t;
im: pjas_image_t;
cmptparams: jas_image_cmptparm_t;
outopts: string;
ww, hh, y, x, vv, colors: integer;
row: PRGB;
yy, cb, cr: integer;
nullpr: TProgressRec;
begin
with nullpr do
begin
Aborting := xProgress.Aborting;
fOnProgress := nil;
Sender := nil;
end;
//
im := nil;
js := jas_stream_fopen(pointer(Stream), 'w+b');
ww := Bitmap.Width;
hh := Bitmap.Height;
cmptparams.tlx := 0;
cmptparams.tly := 0;
cmptparams.hstep := 1;
cmptparams.vstep := 1;
cmptparams.width := ww;
cmptparams.height := hh;
if Bitmap.PixelFormat = ie1g then
begin
IOParams.BitsPerSample := 1;
IOParams.J2000_ColorSpace := ioJ2000_GRAYLEV;
end;
cmptparams.prec := IOParams.BitsPerSample;
colors := (1 shl IOParams.BitsPerSample) - 1;
cmptparams.sgnd := 0;
xProgress.per1 := 100 / hh;
xProgress.val := 0;
case IOParams.J2000_ColorSpace of
ioJ2000_GRAYLEV:
begin
// gray scale or black/white
im := jas_image_create(1, @cmptparams, JAS_IMAGE_CM_GRAY);
iejas_image_setcmpttype(im, 0, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y));
if bitmap.pixelformat = ie24RGB then
begin
// gray scale
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 * gRedToGrayCoef + g * gGreenToGrayCoef + b * gBlueToGrayCoef) div 100) / 255) * colors);
jas_image_writecmptsample(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
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
jas_image_writecmptsample(im, 0, x, y, 1)
else
jas_image_writecmptsample(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
im := jas_image_create0();
iejas_image_setcolorspace(im, JAS_IMAGE_CS_RGB);
jas_image_addcmpt(im, 0, @cmptparams);
jas_image_addcmpt(im, 1, @cmptparams);
jas_image_addcmpt(im, 2, @cmptparams);
iejas_image_setcmpttype(im, 0, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R));
iejas_image_setcmpttype(im, 1, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G));
iejas_image_setcmpttype(im, 2, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B));
for y := 0 to hh - 1 do
begin
row := Bitmap.Scanline[y];
for x := 0 to ww - 1 do
begin
with row^ do
begin
jas_image_writecmptsample(im, 0, x, y, trunc(r / 255 * colors));
jas_image_writecmptsample(im, 1, x, y, trunc(g / 255 * colors));
jas_image_writecmptsample(im, 2, x, y, trunc(b / 255 * colors));
end;
inc(row);
end;
// 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);
iejas_image_setcmpttype(im,0,JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_Y));
iejas_image_setcmpttype(im,1,JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CB));
iejas_image_setcmpttype(im,2,JAS_IMAGE_CT_COLOR(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 );
jas_image_writecmptsample(im,0,x,y,yy);
jas_image_writecmptsample(im,1,x,y,cb);
jas_image_writecmptsample(im,2,x,y,cr);
end;
inc(row);
end;
// OnProgress
with xProgress do
if assigned(fOnProgress) then
fOnProgress(Sender,trunc(per1*y));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -