📄 pngimage.java
字号:
if (colorType == 3) {
PdfArray colorspace = new PdfArray();
colorspace.add(PdfName.INDEXED);
colorspace.add(getColorspace());
colorspace.add(new PdfNumber(len / 3 - 1));
ByteBuffer colortable = new ByteBuffer();
while ((len--) > 0) {
colortable.append_i(is.read());
}
colorspace.add(new PdfString(colorTable = colortable.toByteArray()));
additional.put(PdfName.COLORSPACE, colorspace);
}
else {
Utilities.skip(is, len);
}
}
else if (pHYs.equals(marker)) {
int dx = getInt(is);
int dy = getInt(is);
int unit = is.read();
if (unit == 1) {
dpiX = (int)((float)dx * 0.0254f);
dpiY = (int)((float)dy * 0.0254f);
}
else {
if (dy != 0)
XYRatio = (float)dx / (float)dy;
}
}
else if (cHRM.equals(marker)) {
xW = (float)getInt(is) / 100000f;
yW = (float)getInt(is) / 100000f;
xR = (float)getInt(is) / 100000f;
yR = (float)getInt(is) / 100000f;
xG = (float)getInt(is) / 100000f;
yG = (float)getInt(is) / 100000f;
xB = (float)getInt(is) / 100000f;
yB = (float)getInt(is) / 100000f;
hasCHRM = !(Math.abs(xW)<0.0001f||Math.abs(yW)<0.0001f||Math.abs(xR)<0.0001f||Math.abs(yR)<0.0001f||Math.abs(xG)<0.0001f||Math.abs(yG)<0.0001f||Math.abs(xB)<0.0001f||Math.abs(yB)<0.0001f);
}
else if (sRGB.equals(marker)) {
int ri = is.read();
intent = intents[ri];
gamma = 2.2f;
xW = 0.3127f;
yW = 0.329f;
xR = 0.64f;
yR = 0.33f;
xG = 0.3f;
yG = 0.6f;
xB = 0.15f;
yB = 0.06f;
hasCHRM = true;
}
else if (gAMA.equals(marker)) {
int gm = getInt(is);
if (gm != 0) {
gamma = 100000f / (float)gm;
if (!hasCHRM) {
xW = 0.3127f;
yW = 0.329f;
xR = 0.64f;
yR = 0.33f;
xG = 0.3f;
yG = 0.6f;
xB = 0.15f;
yB = 0.06f;
hasCHRM = true;
}
}
}
else if (iCCP.equals(marker)) {
do {
--len;
} while (is.read() != 0);
is.read();
--len;
byte icccom[] = new byte[len];
int p = 0;
while (len > 0) {
int r = is.read(icccom, p, len);
if (r < 0)
throw new IOException("Premature end of file.");
p += r;
len -= r;
}
byte iccp[] = PdfReader.FlateDecode(icccom, true);
icccom = null;
try {
icc_profile = ICC_Profile.getInstance(iccp);
}
catch (RuntimeException e) {
icc_profile = null;
}
}
else if (IEND.equals(marker)) {
break;
}
else {
Utilities.skip(is, len);
}
Utilities.skip(is, 4);
}
}
PdfObject getColorspace() {
if (icc_profile != null) {
if ((colorType & 2) == 0)
return PdfName.DEVICEGRAY;
else
return PdfName.DEVICERGB;
}
if (gamma == 1f && !hasCHRM) {
if ((colorType & 2) == 0)
return PdfName.DEVICEGRAY;
else
return PdfName.DEVICERGB;
}
else {
PdfArray array = new PdfArray();
PdfDictionary dic = new PdfDictionary();
if ((colorType & 2) == 0) {
if (gamma == 1f)
return PdfName.DEVICEGRAY;
array.add(PdfName.CALGRAY);
dic.put(PdfName.GAMMA, new PdfNumber(gamma));
dic.put(PdfName.WHITEPOINT, new PdfLiteral("[1 1 1]"));
array.add(dic);
}
else {
PdfObject wp = new PdfLiteral("[1 1 1]");
array.add(PdfName.CALRGB);
if (gamma != 1f) {
PdfArray gm = new PdfArray();
PdfNumber n = new PdfNumber(gamma);
gm.add(n);
gm.add(n);
gm.add(n);
dic.put(PdfName.GAMMA, gm);
}
if (hasCHRM) {
float z = yW*((xG-xB)*yR-(xR-xB)*yG+(xR-xG)*yB);
float YA = yR*((xG-xB)*yW-(xW-xB)*yG+(xW-xG)*yB)/z;
float XA = YA*xR/yR;
float ZA = YA*((1-xR)/yR-1);
float YB = -yG*((xR-xB)*yW-(xW-xB)*yR+(xW-xR)*yB)/z;
float XB = YB*xG/yG;
float ZB = YB*((1-xG)/yG-1);
float YC = yB*((xR-xG)*yW-(xW-xG)*yW+(xW-xR)*yG)/z;
float XC = YC*xB/yB;
float ZC = YC*((1-xB)/yB-1);
float XW = XA+XB+XC;
float YW = 1;//YA+YB+YC;
float ZW = ZA+ZB+ZC;
PdfArray wpa = new PdfArray();
wpa.add(new PdfNumber(XW));
wpa.add(new PdfNumber(YW));
wpa.add(new PdfNumber(ZW));
wp = wpa;
PdfArray matrix = new PdfArray();
matrix.add(new PdfNumber(XA));
matrix.add(new PdfNumber(YA));
matrix.add(new PdfNumber(ZA));
matrix.add(new PdfNumber(XB));
matrix.add(new PdfNumber(YB));
matrix.add(new PdfNumber(ZB));
matrix.add(new PdfNumber(XC));
matrix.add(new PdfNumber(YC));
matrix.add(new PdfNumber(ZC));
dic.put(PdfName.MATRIX, matrix);
}
dic.put(PdfName.WHITEPOINT, wp);
array.add(dic);
}
return array;
}
}
Image getImage() throws IOException {
readPng();
try {
int pal0 = 0;
int palIdx = 0;
palShades = false;
if (trans != null) {
for (int k = 0; k < trans.length; ++k) {
int n = trans[k] & 0xff;
if (n == 0) {
++pal0;
palIdx = k;
}
if (n != 0 && n != 255) {
palShades = true;
break;
}
}
}
if ((colorType & 4) != 0)
palShades = true;
genBWMask = (!palShades && (pal0 > 1 || transRedGray >= 0));
if (!palShades && !genBWMask && pal0 == 1) {
additional.put(PdfName.MASK, new PdfLiteral("["+palIdx+" "+palIdx+"]"));
}
boolean needDecode = (interlaceMethod == 1) || (bitDepth == 16) || ((colorType & 4) != 0) || palShades || genBWMask;
switch (colorType) {
case 0:
inputBands = 1;
break;
case 2:
inputBands = 3;
break;
case 3:
inputBands = 1;
break;
case 4:
inputBands = 2;
break;
case 6:
inputBands = 4;
break;
}
if (needDecode)
decodeIdat();
int components = inputBands;
if ((colorType & 4) != 0)
--components;
int bpc = bitDepth;
if (bpc == 16)
bpc = 8;
Image img;
if (image != null)
img = Image.getInstance(width, height, components, bpc, image);
else {
img = new ImgRaw(width, height, components, bpc, idat.toByteArray());
img.setDeflated(true);
PdfDictionary decodeparms = new PdfDictionary();
decodeparms.put(PdfName.BITSPERCOMPONENT, new PdfNumber(bitDepth));
decodeparms.put(PdfName.PREDICTOR, new PdfNumber(15));
decodeparms.put(PdfName.COLUMNS, new PdfNumber(width));
decodeparms.put(PdfName.COLORS, new PdfNumber((colorType == 3 || (colorType & 2) == 0) ? 1 : 3));
additional.put(PdfName.DECODEPARMS, decodeparms);
}
if (additional.get(PdfName.COLORSPACE) == null)
additional.put(PdfName.COLORSPACE, getColorspace());
if (intent != null)
additional.put(PdfName.INTENT, intent);
if (additional.size() > 0)
img.setAdditional(additional);
if (icc_profile != null)
img.tagICC(icc_profile);
if (palShades) {
Image im2 = Image.getInstance(width, height, 1, 8, smask);
im2.makeMask();
img.setImageMask(im2);
}
if (genBWMask) {
Image im2 = Image.getInstance(width, height, 1, 1, smask);
im2.makeMask();
img.setImageMask(im2);
}
img.setDpi(dpiX, dpiY);
img.setXYRatio(XYRatio);
img.setOriginalType(Image.ORIGINAL_PNG);
return img;
}
catch (Exception e) {
throw new ExceptionConverter(e);
}
}
void decodeIdat() {
int nbitDepth = bitDepth;
if (nbitDepth == 16)
nbitDepth = 8;
int size = -1;
bytesPerPixel = (bitDepth == 16) ? 2 : 1;
switch (colorType) {
case 0:
size = (nbitDepth * width + 7) / 8 * height;
break;
case 2:
size = width * 3 * height;
bytesPerPixel *= 3;
break;
case 3:
if (interlaceMethod == 1)
size = (nbitDepth * width + 7) / 8 * height;
bytesPerPixel = 1;
break;
case 4:
size = width * height;
bytesPerPixel *= 2;
break;
case 6:
size = width * 3 * height;
bytesPerPixel *= 4;
break;
}
if (size >= 0)
image = new byte[size];
if (palShades)
smask = new byte[width * height];
else if (genBWMask)
smask = new byte[(width + 7) / 8 * height];
ByteArrayInputStream bai = new ByteArrayInputStream(idat.getBuf(), 0, idat.size());
InputStream infStream = new InflaterInputStream(bai, new Inflater());
dataStream = new DataInputStream(infStream);
if (interlaceMethod != 1) {
decodePass(0, 0, 1, 1, width, height);
}
else {
decodePass(0, 0, 8, 8, (width + 7)/8, (height + 7)/8);
decodePass(4, 0, 8, 8, (width + 3)/8, (height + 7)/8);
decodePass(0, 4, 4, 8, (width + 3)/4, (height + 3)/8);
decodePass(2, 0, 4, 4, (width + 1)/4, (height + 3)/4);
decodePass(0, 2, 2, 4, (width + 1)/2, (height + 1)/4);
decodePass(1, 0, 2, 2, width/2, (height + 1)/2);
decodePass(0, 1, 1, 2, width, height/2);
}
}
void decodePass( int xOffset, int yOffset,
int xStep, int yStep,
int passWidth, int passHeight) {
if ((passWidth == 0) || (passHeight == 0)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -