All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.poi.hwmf.record.HwmfTernaryRasterOp Maven / Gradle / Ivy

Go to download

This OSGi bundle wraps poi, poi-ooxml, and poi-scratchpad ${pkgVersion} jar files.

There is a newer version: 5.2.3_1
Show newest version
/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.hwmf.record;

import java.util.Arrays;
import java.util.Deque;

/**
 * Each ternary raster operation code represents a Boolean operation in which the values of the pixels in
 * the source, the selected brush, and the destination are combined. Following are the three operands
 * used in these operations.
 *
 * 
 * 
 * 
 * 
 * 
 * 
 * 
Raster-operation code meaning
OperandMeaning
DDestination bitmap
PSelected brush (also called pattern)
SSource bitmap
* * Following are the Boolean operators used in these operations. * * * * * * * *
Boolean operator meaning
OperandMeaning
aBitwise AND
nBitwise NOT (inverse)
oBitwise OR
xBitwise exclusive OR (XOR)
* * All Boolean operations are presented in reverse Polish notation. For example, the following operation * replaces the values of the pixels in the destination bitmap with a combination of the pixel values of the * source and brush: PSo. * * The following operation combines the values of the pixels in the source and brush with the pixel values * of the destination bitmap: DPSoo (there are alternative spellings of some functions, so although a * particular spelling MAY NOT be listed in the enumeration, an equivalent form SHOULD be). * * Each raster operation code is a 32-bit integer whose high-order word is a Boolean operation index and * whose low-order word is the operation code. The 16-bit operation index is a zero-extended, 8-bit * value that represents the result of the Boolean operation on predefined brush, source, and destination * values. For example, the operation indexes for the PSo and DPSoo operations are shown in the * following list. * * * * * * * * * * * * *
Raster-operation examples
PSDDPoDPan
00000
00101
01011
01111
10011
10111
11011
11111
* * The operation indexes are determined by reading the binary values in a column of the table from the * bottom up. For example, in the PSo column, the binary value is 11111100, which is equivalent to 00FC * (hexadecimal is implicit for these values), which is the operation index for PSo. * * Using this method, DPSoo can be seen to have the operation index 00FE. Operation indexes define the * locations of corresponding raster operation codes in the preceding enumeration. The PSo operation is * in line 252 (0x00FC) of the enumeration; DPSoo is in line 254 (0x00FE). * * The most commonly used raster operations have been given explicit enumeration names, which * SHOULD be used; examples are PATCOPY and WHITENESS. * * When the source and destination bitmaps are monochrome, a bit value of 0 represents a black pixel * and a bit value of 1 represents a white pixel. When the source and the destination bitmaps are color, * those colors are represented with red green blue (RGB) values. */ @SuppressWarnings("unused") public enum HwmfTernaryRasterOp { /** Fills the destination rectangle with black */ BLACKNESS(0x00000042), DPSOON(0x00010289), DPSONA(0x00020C89), PSON(0x000300AA), SDPONA(0x00040C88), DPON(0x000500A9), PDSXNON(0x00060865), PDSAON(0x000702C5), SDPNAA(0x00080F08), PDSXON(0x00090245), DPNA(0x000A0329), PSDNAON(0x000B0B2A), SPNA(0x000C0324), PDSNAON(0x000D0B25), PDSONON(0x000E08A5), PN(0x000F0001), PDSONA(0x00100C85), /** Fills the destination area with (not (Dst or Src)) */ NOTSRCERASE(0x001100A6), SDPXNON(0x00120868), SDPAON(0x001302C8), DPSXNON(0x00140869), DPSAON(0x001502C9), PSDPSANAXX(0x00165CCA), SSPXDSXAXN(0x00171D54), SPXPDXA(0x00180D59), SDPSANAXN(0x00191CC8), PDSPAOX(0x001A06C5), SDPSXAXN(0x001B0768), PSDPAOX(0x001C06CA), DSPDXAXN(0x001D0766), PDSOX(0x001E01A5), PDSOAN(0x001F0385), DPSNAA(0x00200F09), SDPXON(0x00210248), DSNA(0x00220326), SPDNAON(0x00230B24), SPXDSXA(0x00240D55), PDSPANAXN(0x00251CC5), SDPSAOX(0x002606C8), SDPSXNOX(0x00271868), DPSXA(0x00280369), PSDPSAOXXN(0x002916CA), DPSANA(0x002A0CC9), SSPXPDXAXN(0x002B1D58), SPDSOAX(0x002C0784), PSDNOX(0x002D060A), PSDPXOX(0x002E064A), PSDNOAN(0x002F0E2A), PSNA(0x0030032A), SDPNAON(0x00310B28), SDPSOOX(0x00320688), /** Fills the destination area with (not Src) */ NOTSRCCOPY(0x00330008), SPDSAOX(0x003406C4), SPDSXNOX(0x00351864), SDPOX(0x003601A8), SDPOAN(0x00370388), PSDPOAX(0x0038078A), SPDNOX(0x0390604), SPDSXOX(0x003A0644), SPDNOAN(0x003B0E24), PSX(0x003C004A), SPDSONOX(0x003D18A4), SPDSNAOX(0x003E1B24), PSAN(0x003F00EA), PSDNAA(0x00400F0A), DPSXON(0x00410249), SDXPDXA(0x00420D5D), SPDSANAXN(0x00431CC4), /** Fills the destination area with ((not Dst) and Src) */ SRCERASE(0x00440328), DPSNAON(0x00450B29), DSPDAOX(0x004606C6), PSDPXAXN(0x0047076A), SDPXA(0x00480368), PDSPDAOXXN(0x004916C5), DPSDOAX(0x004A0789), PDSNOX(0x004B0605), SDPANA(0x004C0CC8), SSPXDSXOXN(0x004D1954), PDSPXOX(0x004E0645), PDSNOAN(0x004F0E25), PDNA(0x00500325), DSPNAON(0x00510B26), DPSDAOX(0x005206C9), SPDSXAXN(0x00530764), DPSONON(0x005408A9), /** Inverts the colors of the destination area */ DSTINVERT(0x00550009), DPSOX(0x005601A9), DPSOAN(0x000570389), PDSPOAX(0x00580785), DPSNOX(0x00590609), /** Fills the destination area with (Dst xor Pattern) */ PATINVERT(0x005A0049), DPSDONOX(0x005B18A9), DPSDXOX(0x005C0649), DPSNOAN(0x005D0E29), DPSDNAOX(0x005E1B29), DPAN(0x005F00E9), PDSXA(0x00600365), DSPDSAOXXN(0x006116C6), DSPDOAX(0x00620786), SDPNOX(0x00630608), SDPSOAX(0x00640788), DSPNOX(0x00650606), /** Fills the destination area with (Dst xor Src) */ SRCINVERT(0x00660046), SDPSONOX(0x006718A8), DSPDSONOXXN(0x006858A6), PDSXXN(0x00690145), DPSAX(0x006A01E9), PSDPSOAXXN(0x006B178A), SDPAX(0x006C01E8), PDSPDOAXXN(0x006D1785), SDPSNOAX(0x006E1E28), PDSXNAN(0x006F0C65), PDSANA(0x00700CC5), SSDXPDXAXN(0x00711D5C), SDPSXOX(0x00720648), SDPNOAN(0x00730E28), DSPDXOX(0x00740646), DSPNOAN(0x00750E26), SDPSNAOX(0x00761B28), DSAN(0x007700E6), PDSAX(0x007801E5), DSPDSOAXXN(0x00791786), DPSDNOAX(0x007A1E29), SDPXNAN(0x007B0C68), SPDSNOAX(0x007C1E24), DPSXNAN(0x007D0C69), SPXDSXO(0x007E0955), DPSAAN(0x007F03C9), DPSAA(0x008003E9), SPXDSXON(0x00810975), DPSXNA(0x00820C49), SPDSNOAXN(0x00831E04), SDPXNA(0x00840C48), PDSPNOAXN(0x00851E05), DSPDSOAXX(0x008617A6), PDSAXN(0x008701C5), /** Fills the destination area with (Dst and Src) */ SRCAND(0x008800C6), SDPSNAOXN(0x00891B08), DSPNOA(0x008A0E06), DSPDXOXN(0x008B0666), SDPNOA(0x008C0E08), SDPSXOXN(0x008D0668), SSDXPDXAX(0x008E1D7C), PDSANAN(0x008F0CE5), PDSXNA(0x00900C45), SDPSNOAXN(0x00911E08), DPSDPOAXX(0x009217A9), SPDAXN(0x009301C4), PSDPSOAXX(0x009417AA), DPSAXN(0x009501C9), DPSXX(0x00960169), PSDPSONOXX(0x0097588A), SDPSONOXN(0x00981888), DSXN(0x00990066), DPSNAX(0x009A0709), SDPSOAXN(0x009B07A8), SPDNAX(0x009C0704), DSPDOAXN(0x009D07A6), DSPDSAOXX(0x009E16E6), PDSXAN(0x009F0345), DPA(0x00A000C9), PDSPNAOXN(0x00A11B05), DPSNOA(0x00A20E09), DPSDXOXN(0x00A30669), PDSPONOXN(0x00A41885), PDXN(0x00A50065), DSPNAX(0x00A60706), PDSPOAXN(0x00A707A5), DPSOA(0x00A803A9), DPSOXN(0x00A90189), D(0x00AA0029), DPSONO(0x00AB0889), SPDSXAX(0x00AC0744), DPSDAOXN(0x00AD06E9), DSPNAO(0x00AE0B06), DPNO(0x00AF0229), PDSNOA(0x00B00E05), PDSPXOXN(0x00B10665), SSPXDSXOX(0x00B21974), SDPANAN(0x00B30CE8), PSDNAX(0x00B4070A), DPSDOAXN(0x00B507A9), DPSDPAOXX(0x00B616E9), SDPXAN(0x00B70348), PSDPXAX(0x00B8074A), DSPDAOXN(0x00B906E6), DPSNAO(0x00BA0B09), /** Fills the destination area with (Dst or not Src) */ MERGEPAINT(0x00BB0226), SPDSANAX(0x00BC1CE4), SDXPDXAN(0x00BD0D7D), DPSXO(0x00BE0269), DPSANO(0x00BF08C9), /** Fills the destination area with (Src and Pattern) */ MERGECOPY(0x00C000CA), SPDSNAOXN(0x00C11B04), SPDSONOXN(0x00C21884), PSXN(0x00C3006A), SPDNOA(0x00C40E04), SPDSXOXN(0x00C50664), SDPNAX(0x00C60708), PSDPOAXN(0x00C707AA), SDPOA(0x00C803A8), SPDOXN(0x00C90184), DPSDXAX(0x00CA0749), SPDSAOXN(0x00CB06E4), /** Fills the destination area with Src */ SRCCOPY(0x00CC0020), SDPONO(0x00CD0888), SDPNAO(0x00CE0B08), SPNO(0x00CF0224), PSDNOA(0x00D00E0A), PSDPXOXN(0x00D1066A), PDSNAX(0x00D20705), SPDSOAXN(0x00D307A4), SSPXPDXAX(0x00D41D78), DPSANAN(0x00D50CE9), PSDPSAOXX(0x00D616EA), DPSXAN(0x00D70349), PDSPXAX(0x00D80745), SDPSAOXN(0x00D906E8), DPSDANAX(0x00DA1CE9), SPXDSXAN(0x00DB0D75), SPDNAO(0x00DC0B04), SDNO(0x00DD0228), SDPXO(0x00DE0268), SDPANO(0x00DF08C8), PDSOA(0x00E003A5), PDSOXN(0x00E10185), DSPDXAX(0x00E20746), PSDPAOXN(0x00E306EA), SDPSXAX(0x00E40748), PDSPAOXN(0x00E506E5), SDPSANAX(0x00E61CE8), SPXPDXAN(0x00E70D79), SSPXDSXAX(0x00E81D74), DSPDSANAXXN(0x00E95CE6), DPSAO(0x00EA02E9), DPSXNO(0x00EB0849), SDPAO(0x00EC02E8), SDPXNO(0x00ED0848), /** Combines the colors of the source and the destination using the operator OR on each pixel */ SRCPAINT(0x00EE0086), SDPNOO(0x00EF0A08), /** Fills the destination area with (Pattern) */ PATCOPY(0x00F00021), PDSONO(0x00F10885), PDSNAO(0x00F20B05), PSNO(0x00F3022A), PSDNAO(0x00F40B0A), PDNO(0x00F50225), PDSXO(0x00F60265), PDSANO(0x00F708C5), PDSAO(0x00F802E5), PDSXNO(0x00F90845), DPO(0x00FA0089), /** Fills the destination area with (Dst or (not Src) or Pattern) */ PATPAINT(0x00FB0A09), PSO(0x00FC008A), PSDNOO(0x00FD0A0A), DPSOO(0x00FE02A9), /** Fills the destination rectangle with white */ WHITENESS(0x00FF0062); private static final String[] ARG_ORDER = { "SSSSSS","PPPPPP","DDDDDD",null, "SPDSPD","PDSPDS","DSPDSP",null, "SDPSDP","DPSDPS","PSDPSD",null, null, null, null, null, null, null, null, null, "SSP.DS", "SP.DS", null, null, "SSP.PD", "SP.PD", null, null, "SSD.PD", "SD.PD", null, null }; private static final String OPS = "nxoa"; private final int opValue; HwmfTernaryRasterOp(int opValue) { this.opValue=opValue; } public static HwmfTernaryRasterOp valueOf(int opIndex) { for (HwmfTernaryRasterOp bb : HwmfTernaryRasterOp.values()) { if (bb.getOpIndex() == opIndex) { return bb; } } return null; } public int getOpIndex() { return opValue >>> 16; } public int getOpCode() { return opValue & 0xFFFF; } public String describeCmd() { String[] stack = new String[10]; int stackPnt = 0; for (char c : calcCmd().toCharArray()) { switch (c) { case 'S': case 'D': case 'P': stack[stackPnt++] = ""+c; break; case 'n': stack[stackPnt-1] = "not("+stack[stackPnt-1]+")"; break; case 'a': stack[stackPnt-2] = "("+stack[stackPnt-1]+" and "+stack[stackPnt-2]+")"; stackPnt--; break; case 'o': stack[stackPnt-2] = "("+stack[stackPnt-1]+" or "+stack[stackPnt-2]+")"; stackPnt--; break; case 'x': stack[stackPnt-2] = "("+stack[stackPnt-1]+" xor "+stack[stackPnt-2]+")"; stackPnt--; break; case '1': stack[stackPnt++] = "all white"; break; case '0': stack[stackPnt++] = "all black"; break; default: throw new RuntimeException("unknown cmd '"+c+"'."); } } return stack[--stackPnt]; } public String calcCmd() { // taken from https://wiki.winehq.org/Ternary_Raster_Ops // bit 0-4: Specify the order of arguments to the raster operation String argOrder = ARG_ORDER[this.opValue & 0x001F]; assert(argOrder != null); // The boolean operators, 1st (6-7 bit), 2nd (8-9 bit), 3rd (a-b bit), 4th (c-d bit), 5th (e-f bit) int nbrOfOps = 0; int[] opArr = new int[5]; for (int i=0, bit=6; i>> bit) & 0x03) != 0) { nbrOfOps = i+1; } } StringBuilder sbArg = new StringBuilder(), sbOp = new StringBuilder(); sbArg.append(argOrder.charAt(0)); for (int opIdx=0,argIdx=1; opIdx < nbrOfOps; opIdx++) { char opCh = OPS.charAt(opArr[opIdx]); char ch = argOrder.charAt(argIdx); sbOp.append(opCh); if (ch == '.') { sbArg.insert(argIdx, sbOp.charAt(0)); sbOp.deleteCharAt(0); } if (opCh == 'n') { continue; } sbArg.append(ch == '.' ? argOrder.charAt(++argIdx) : ch); argIdx++; } sbArg.append(sbOp); // bit 5: Used to apply the NOT operator to the results of the other operations // if 0, there are a ODD number of operations, even number otherwise if ((nbrOfOps % 2) == ((this.opValue >>> 0x05) & 1)) { sbArg.append('n'); } String ret = sbArg.toString(); return ret.startsWith("DDx") ? "DDx".equals(ret) ? "0" : "1" : ret; } public void process(Deque stack, int[] dst, int[] src, int[] pat) { for (char op : calcCmd().toCharArray()) { switch (op) { case 'S': opS(stack, dst, src, pat); break; case 'P': opP(stack, dst, src, pat); break; case 'D': opD(stack, dst, src, pat); break; case 'n': opN(stack, dst, src, pat); break; case 'a': opA(stack, dst, src, pat); break; case 'o': opO(stack, dst, src, pat); break; case 'x': opX(stack, dst, src, pat); break; case '1': op1(stack, dst, src, pat); break; case '0': op0(stack, dst, src, pat); break; default: throw new IllegalStateException(); } } } private static void opS(Deque stack, int[] dst, int[] src, int[] pat) { stack.push(src); } private static void opP(Deque stack, int[] dst, int[] src, int[] pat) { stack.push(pat); } private static void opD(Deque stack, int[] dst, int[] src, int[] pat) { stack.push(dst); } private static void opN(Deque stack, int[] dst, int[] src, int[] pat) { int[] oper = checkClone(stack.pop(), dst, src, pat, true); for (int i=0; i stack, int[] dst, int[] src, int[] pat) { int[] oper1 = checkClone(stack.pop(), dst, src, pat, true); int[] oper2 = checkClone(stack.pop(), dst, src, pat, false); for (int i=0; i stack, int[] dst, int[] src, int[] pat) { int[] oper1 = checkClone(stack.pop(), dst, src, pat, true); int[] oper2 = checkClone(stack.pop(), dst, src, pat, false); for (int i=0; i stack, int[] dst, int[] src, int[] pat) { int[] oper1 = checkClone(stack.pop(), dst, src, pat, true); int[] oper2 = checkClone(stack.pop(), dst, src, pat, false); for (int i=0; i stack, int[] dst, int[] src, int[] pat) { int[] oper = new int[dst.length]; Arrays.fill(oper, 0xFFFFFFFF); stack.push(oper); } private static void op0(Deque stack, int[] dst, int[] src, int[] pat) { int[] oper = new int[dst.length]; Arrays.fill(oper, 0xFF000000); stack.push(oper); } private static int[] checkClone(int[] oper, int[] dst, int[] src, int[] pat, boolean force) { if (force && (oper == src || oper == pat || oper == dst)) { return oper.clone(); } else { return oper; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy