Source code: com/sixlegs/image/png/Chunk_cHRM.java
1 // Copyright (C) 1998, 1999, 2001 Chris Nokleberg
2 // Please see included LICENSE.TXT
3
4 package com.sixlegs.image.png;
5 import java.io.IOException;
6
7 class Chunk_cHRM
8 extends Chunk
9 {
10 protected long xwlong, ywlong, xrlong, yrlong, xglong, yglong, xblong, yblong;
11 protected double xw, yw, xr, yr, xg, yg, xb, yb;
12 protected double Xw, Yw, Zw;
13 protected double Xr, Yr, Zr;
14 protected double Xg, Yg, Zg;
15 protected double Xb, Yb, Zb;
16
17 Chunk_cHRM()
18 {
19 super(cHRM);
20 }
21
22 protected boolean multipleOK()
23 {
24 return false;
25 }
26
27 protected boolean beforeIDAT()
28 {
29 return true;
30 }
31
32 /*
33 zr = 1 - (xr + yr)
34 zg = 1 - (xg + yg)
35 zb = 1 - (xb + yb)
36 zw = 1 - (xw + yw)
37
38 / r \ / xr xg xb \-1 / xw / yw \
39 | g | = | yr yg yb | | yw / yw |
40 \ b / \ zr zg zb / \ zw / yw /
41
42 det: xr*yg*zb + xg*yb*zr + xb*yr*zg - xg*yr*zb - xr*yb*zg - xb*yg*zr
43
44 Yr = r * yr
45 Yg = g * yg
46 Yb = b * yb
47 */
48
49 protected void calc()
50 {
51 double zr = 1 - (xr + yr);
52 double zg = 1 - (xg + yg);
53 double zb = 1 - (xb + yb);
54 double zw = 1 - (xw + yw);
55
56 Xw = xw / yw;
57 Yw = 1; /* yw / yw; */
58 Zw = zw / yw;
59
60 double det = xr*(yg*zb-zg*yb)-xg*(yr*zb-zr*yb)+xb*(yr*zg-zr*yg);
61 double fr = (Xw*(yg*zb-zg*yb)-xg*(zb-Zw*yb)+xb*(zg-Zw*yg))/det;
62 double fg = (xr*(zb-Zw*yb)-Xw*(yr*zb-zr*yb)+xb*(yr*Zw-zr))/det;
63 double fb = (xr*(yg*Zw-zg)-xg*(yr*Zw-zr)+Xw*(yr*zg-zr*yg))/det;
64
65 Xr = fr * xr; Yr = fr * yr; Zr = fr * zr;
66 Xg = fg * xg; Yg = fg * yg; Zg = fg * zg;
67 Xb = fb * xb; Yb = fb * yb; Zb = fb * zb;
68
69 if (img.getChunk(sRGB) == null) {
70 img.data.properties.put("chromaticity xy",
71 new long[][]{{xwlong,ywlong},
72 {xrlong,yrlong},
73 {xglong,yglong},
74 {xblong,yblong}});
75 img.data.properties.put("chromaticity xyz",
76 new double[][]{{Xw, Yw, Zw},
77 {Xr, Yr, Zr},
78 {Xg, Yg, Zg},
79 {Xb, Yb, Zb}});
80 }
81 }
82
83 protected void readData()
84 throws IOException
85 {
86 if (img.data.palette != null)
87 throw new PngException("cHRM chunk must precede PLTE chunk");
88 if (length != 32) badLength(32);
89 checkRange(xw = (double)(xwlong = in_data.readUnsignedInt()) / 100000, "white");
90 checkRange(yw = (double)(ywlong = in_data.readUnsignedInt()) / 100000, "white");
91 checkRange(xr = (double)(xrlong = in_data.readUnsignedInt()) / 100000, "red");
92 checkRange(yr = (double)(yrlong = in_data.readUnsignedInt()) / 100000, "red");
93 checkRange(xg = (double)(xglong = in_data.readUnsignedInt()) / 100000, "green");
94 checkRange(yg = (double)(yglong = in_data.readUnsignedInt()) / 100000, "green");
95 checkRange(xb = (double)(xblong = in_data.readUnsignedInt()) / 100000, "blue");
96 checkRange(yb = (double)(yblong = in_data.readUnsignedInt()) / 100000, "blue");
97
98 calc();
99 }
100
101 private void checkRange(double value, String color)
102 throws PngException
103 {
104 if (value < 0 || value > 0.8)
105 throw new PngExceptionSoft("Invalid cHRM " + color + " point");
106 }
107 }