return 1; } private String[] printExecCmd(String printer, String options, boolean noJobSheet, String banner, int copies, String spoolFile) { int PRINTER = 0x1; int OPTIONS = 0x2; int BANNER = 0x4; int COPIES = 0x8; int NOSHEET = 0x10; int pFlags = 0; String execCmd[]; int ncomps = 2; // minimum number of print args int n = 0; if (printer != null && !printer.equals("") && !printer.equals("lp")) { pFlags |= PRINTER; ncomps+=1; } if (options != null && !options.equals("")) { pFlags |= OPTIONS; ncomps+=1; } if (banner != null && !banner.equals("")) { pFlags |= BANNER; ncomps+=1; } if (copies > 1) { pFlags |= COPIES; ncomps+=1; } if (noJobSheet) { pFlags |= NOSHEET; ncomps+=1; } if (System.getProperty("os.name").equals("Linux")) { execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lpr"; if ((pFlags & PRINTER) != 0) { execCmd[n++] = "-P" + printer; } if ((pFlags & BANNER) != 0) { execCmd[n++] = "-J" + banner; } if ((pFlags & COPIES) != 0) { execCmd[n++] = "-#" + copies; } if ((pFlags & NOSHEET) != 0) { execCmd[n++] = "-h"; } if ((pFlags & OPTIONS) != 0) { execCmd[n++] = new String(options); } } else { ncomps+=1; //add 1 arg for lp execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lp"; execCmd[n++] = "-c"; // make a copy of the spool file if ((pFlags & PRINTER) != 0) { execCmd[n++] = "-d" + printer; } if ((pFlags & BANNER) != 0) { execCmd[n++] = "-t" + banner; } if ((pFlags & COPIES) != 0) { execCmd[n++] = "-n" + copies; } if ((pFlags & NOSHEET) != 0) { execCmd[n++] = "-o nobanner"; } if ((pFlags & OPTIONS) != 0) { execCmd[n++] = "-o" + options; } } execCmd[n++] = spoolFile; return execCmd; } private static int swapBGRtoRGB(byte[] image, int index, byte[] dest) { int destIndex = 0; while(index < image.length-2 && destIndex < dest.length-2) { dest[destIndex++] = image[index+2]; dest[destIndex++] = image[index+1]; dest[destIndex++] = image[index+0]; index+=3; } return index; } /* * Currently CharToByteConverter.getCharacterEncoding() return values are * not fixed yet. These are used as the part of the key of * psfont.propeties. When those name are fixed this routine can * be erased. */ private String makeCharsetName(String name, char[] chs) { if (name.equals("Cp1252") || name.equals("ISO8859_1")) { return "latin1"; } else if (name.equals("UTF8")) { // same as latin 1 if all chars < 256 for (int i=0; i < chs.length; i++) { if (chs[i] > 255) { return name.toLowerCase(); } } return "latin1"; } else if (name.startsWith("ISO8859")) { // same as latin 1 if all chars < 128 for (int i=0; i < chs.length; i++) { if (chs[i] > 127) { return name.toLowerCase(); } } return "latin1"; } else { return name.toLowerCase(); } } private void prepDrawing() { /* Pop gstates until we can set the needed clip * and transform or until we are at the outer most * gstate. */ while (isOuterGState() == false && (getGState().canSetClip(mLastClip) == false || getGState().mTransform.equals(mLastTransform) == false)) { grestore(); } /* Set the color. This can push the color to the * outer most gsave which is often a good thing. */ getGState().emitPSColor(mLastColor); /* We do not want to change the outermost * transform or clip so if we are at the * outer clip the generate a gsave. */ if (isOuterGState()) { gsave(); getGState().emitTransform(mLastTransform); getGState().emitPSClip(mLastClip); } /* Set the font if we have been asked to. It is * important that the font is set after the * transform in order to get the font size * correct. */// if (g != null) {// getGState().emitPSFont(g, mLastFont);// } } /** * Return the GState that is currently on top * of the GState stack. There should always be * a GState on top of the stack. If there isn't * then this method will throw an IndexOutOfBounds * exception. */ private GState getGState() { int count = mGStateStack.size(); return (GState) mGStateStack.get(count - 1); } /** * Emit a PostScript gsave command and add a * new GState on to our stack which represents * the printer's gstate stack. */ private void gsave() { GState oldGState = getGState(); mGStateStack.add(new GState(oldGState)); mPSStream.println(GSAVE_STR); } /** * Emit a PostScript grestore command and remove * a GState from our stack which represents the * printer's gstate stack. */ private void grestore() { int count = mGStateStack.size(); mGStateStack.remove(count - 1); mPSStream.println(GRESTORE_STR); } /** * Return true if the current GState is the * outermost GState and therefore should not * be restored. */ private boolean isOuterGState() { return mGStateStack.size() == 1; } /** * A stack of GStates is maintained to model the printer's * gstate stack. Each GState holds information about * the current graphics attributes. */ private class GState{ Color mColor; Shape mClip; Font mFont; AffineTransform mTransform; GState() { mColor = Color.black; mClip = null; mFont = null; mTransform = new AffineTransform(); } GState(GState copyGState) { mColor = copyGState.mColor; mClip = copyGState.mClip; mFont = copyGState.mFont; mTransform = copyGState.mTransform; } boolean canSetClip(Shape clip) { return mClip == null || mClip.equals(clip); } void emitPSClip(Shape clip) { if (clip != null && (mClip == null || mClip.equals(clip) == false)) { String saveFillOp = mFillOpStr; String saveClipOp = mClipOpStr; convertToPSPath(clip.getPathIterator(new AffineTransform())); selectClipPath(); mClip = clip; /* The clip is a shape and has reset the winding rule state */ mClipOpStr = saveFillOp; mFillOpStr = saveFillOp; } } void emitTransform(AffineTransform transform) { if (transform != null && transform.equals(mTransform) == false) { double[] matrix = new double[6]; transform.getMatrix(matrix); mPSStream.println("[" + (float)matrix[0] + " " + (float)matrix[1] + " " + (float)matrix[2] + " " + (float)matrix[3] + " " + (float)matrix[4] + " " + (float)matrix[5] + "] concat"); mTransform = transform; } } void emitPSColor(Color color) { if (color != null && color.equals(mColor) == false) { float[] rgb = color.getRGBColorComponents(null); /* If the color is a gray value then use * setgray. */ if (rgb[0] == rgb[1] && rgb[1] == rgb[2]) { mPSStream.println(rgb[0] + SETGRAY_STR); /* It's not gray so use setrgbcolor. */ } else { mPSStream.println(rgb[0] + " " + rgb[1] + " " + rgb[2] + " " + SETRGBCOLOR_STR); } mColor = color; } } void emitPSFont(int psFontIndex, float fontSize) { mPSStream.println(fontSize + " " + psFontIndex + " " + SetFontName); } } /** * Given a Java2D <code>PathIterator</code> instance, * this method translates that into a PostScript path.. */ void convertToPSPath(PathIterator pathIter) { float[] segment = new float[6]; int segmentType; /* Map the PathIterator's fill rule into the PostScript * fill rule. */ int fillRule; if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) { fillRule = FILL_EVEN_ODD; } else { fillRule = FILL_WINDING; } beginPath(); setFillMode(fillRule); while (pathIter.isDone() == false) { segmentType = pathIter.currentSegment(segment); switch (segmentType) { case PathIterator.SEG_MOVETO: moveTo(segment[0], segment[1]); break; case PathIterator.SEG_LINETO: lineTo(segment[0], segment[1]); break; /* Convert the quad path to a bezier. */ case PathIterator.SEG_QUADTO: float lastX = getPenX(); float lastY = getPenY(); float c1x = lastX + (segment[0] - lastX) * 2 / 3; float c1y = lastY + (segment[1] - lastY) * 2 / 3; float c2x = segment[2] - (segment[2] - segment[0]) * 2/ 3; float c2y = segment[3] - (segment[3] - segment[1]) * 2/ 3; bezierTo(c1x, c1y, c2x, c2y, segment[2], segment[3]); break; case PathIterator.SEG_CUBICTO: bezierTo(segment[0], segment[1], segment[2], segment[3], segment[4], segment[5]); break; case PathIterator.SEG_CLOSE: closeSubpath(); break; } pathIter.next(); } } /* * Fill the path defined by <code>pathIter</code> * with the specified color. * The path is provided in current user space. */ protected void deviceFill(PathIterator pathIter, Color color, AffineTransform tx, Shape clip) { setTransform(tx); setClip(clip); setColor(color); convertToPSPath(pathIter); /* Specify the path to fill as the clip, this ensures that only * pixels which are inside the path will be filled, which is * what the Java 2D APIs specify */ mPSStream.println(GSAVE_STR); selectClipPath(); fillPath(); mPSStream.println(GRESTORE_STR + " " + NEWPATH_STR); } /* * Run length encode byte array in a form suitable for decoding * by the PS Level 2 filter RunLengthDecode. * Array data to encode is inArr. Encoded data is written to outArr * outArr must be long enough to hold the encoded data but this * can't be known ahead of time. * A safe assumption is to use double the length of the input array. * This is then copied into a new array of the correct length which * is returned. * Algorithm: * Encoding is a lead byte followed by data bytes. * Lead byte of 0->127 indicates leadByte + 1 distinct bytes follow * Lead byte of 129->255 indicates 257 - leadByte is the number of times * the following byte is repeated in the source. * 128 is a special lead byte indicating end of data (EOD) and is * written as the final byte of the returned encoded data. */ private byte[] rlEncode(byte[] inArr) { int inIndex = 0; int outIndex = 0; int startIndex = 0; int runLen = 0; byte[] outArr = new byte[(inArr.length * 2) +2]; while (inIndex < inArr.length) { if (runLen == 0) { startIndex = inIndex++; runLen=1; } while (runLen < 128 && inIndex < inArr.length && inArr[inIndex] == inArr[startIndex]) { runLen++; // count run of same value inIndex++; } if (runLen > 1) { outArr[outIndex++] = (byte)(257 - runLen); outArr[outIndex++] = inArr[startIndex]; runLen = 0; continue; // back to top of while loop. } // if reach here have a run of different values, or at the end. while (runLen < 128 && inIndex < inArr.length && inArr[inIndex] != inArr[inIndex-1]) { runLen++; // count run of different values inIndex++; } outArr[outIndex++] = (byte)(runLen - 1); for (int i = startIndex; i < startIndex+runLen; i++) { outArr[outIndex++] = inArr[i]; } runLen = 0; } outArr[outIndex++] = (byte)128; byte[] encodedData = new byte[outIndex]; System.arraycopy(outArr, 0, encodedData, 0, outIndex); return encodedData; } /* written acc. to Adobe Spec. "Filtered Files: ASCIIEncode Filter", * "PS Language Reference Manual, 2nd edition: Section 3.13" */ private byte[] ascii85Encode(byte[] inArr) { byte[] outArr = new byte[((inArr.length+4) * 5 / 4) + 2]; long p1 = 85; long p2 = p1*p1; long p3 = p1*p2; long p4 = p1*p3; byte pling = '!'; int i = 0; int olen = 0; long val, rem; while (i+3 < inArr.length) { val = ((long)((inArr[i++]&0xff))<<24) + ((long)((inArr[i++]&0xff))<<16) + ((long)((inArr[i++]&0xff))<< 8) + ((long)(inArr[i++]&0xff)); if (val == 0) { outArr[olen++] = 'z'; } else { rem = val; outArr[olen++] = (byte)(rem / p4 + pling); rem = rem % p4; outArr[olen++] = (byte)(rem / p3 + pling); rem = rem % p3; outArr[olen++] = (byte)(rem / p2 + pling); rem = rem % p2; outArr[olen++] = (byte)(rem / p1 + pling); rem = rem % p1; outArr[olen++] = (byte)(rem + pling); } } // input not a multiple of 4 bytes, write partial output. if (i < inArr.length) { int n = inArr.length - i; // n bytes remain to be written val = 0; while (i < inArr.length) { val = (val << 8) + (inArr[i++]&0xff); } int append = 4 - n; while (append-- > 0) { val = val << 8; } byte []c = new byte[5]; rem = val; c[0] = (byte)(rem / p4 + pling); rem = rem % p4; c[1] = (byte)(rem / p3 + pling); rem = rem % p3; c[2] = (byte)(rem / p2 + pling); rem = rem % p2; c[3] = (byte)(rem / p1 + pling); rem = rem % p1; c[4] = (byte)(rem + pling); for (int b = 0; b < n+1 ; b++) { outArr[olen++] = c[b]; } }Lines 1501–2000 of 2213. Previous lines Load more
return 1; } private String[] printExecCmd(String printer, String options, boolean noJobSheet, String banner, int copies, String spoolFile) { int PRINTER = 0x1; int OPTIONS = 0x2; int BANNER = 0x4; int COPIES = 0x8; int NOSHEET = 0x10; int pFlags = 0; String execCmd[]; int ncomps = 2; // minimum number of print args int n = 0; if (printer != null && !printer.equals("") && !printer.equals("lp")) { pFlags |= PRINTER; ncomps+=1; } if (options != null && !options.equals("")) { pFlags |= OPTIONS; ncomps+=1; } if (banner != null && !banner.equals("")) { pFlags |= BANNER; ncomps+=1; } if (copies > 1) { pFlags |= COPIES; ncomps+=1; } if (noJobSheet) { pFlags |= NOSHEET; ncomps+=1; } if (System.getProperty("os.name").equals("Linux")) { execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lpr"; if ((pFlags & PRINTER) != 0) { execCmd[n++] = "-P" + printer; } if ((pFlags & BANNER) != 0) { execCmd[n++] = "-J" + banner; } if ((pFlags & COPIES) != 0) { execCmd[n++] = "-#" + copies; } if ((pFlags & NOSHEET) != 0) { execCmd[n++] = "-h"; } if ((pFlags & OPTIONS) != 0) { execCmd[n++] = new String(options); } } else { ncomps+=1; //add 1 arg for lp execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lp"; execCmd[n++] = "-c"; // make a copy of the spool file if ((pFlags & PRINTER) != 0) { execCmd[n++] = "-d" + printer; } if ((pFlags & BANNER) != 0) { execCmd[n++] = "-t" + banner; } if ((pFlags & COPIES) != 0) { execCmd[n++] = "-n" + copies; } if ((pFlags & NOSHEET) != 0) { execCmd[n++] = "-o nobanner"; } if ((pFlags & OPTIONS) != 0) { execCmd[n++] = "-o" + options; } } execCmd[n++] = spoolFile; return execCmd; } private static int swapBGRtoRGB(byte[] image, int index, byte[] dest) { int destIndex = 0; while(index < image.length-2 && destIndex < dest.length-2) { dest[destIndex++] = image[index+2]; dest[destIndex++] = image[index+1]; dest[destIndex++] = image[index+0]; index+=3; } return index; } /* * Currently CharToByteConverter.getCharacterEncoding() return values are * not fixed yet. These are used as the part of the key of * psfont.propeties. When those name are fixed this routine can * be erased. */ private String makeCharsetName(String name, char[] chs) { if (name.equals("Cp1252") || name.equals("ISO8859_1")) { return "latin1"; } else if (name.equals("UTF8")) { // same as latin 1 if all chars < 256 for (int i=0; i < chs.length; i++) { if (chs[i] > 255) { return name.toLowerCase(); } } return "latin1"; } else if (name.startsWith("ISO8859")) { // same as latin 1 if all chars < 128 for (int i=0; i < chs.length; i++) { if (chs[i] > 127) { return name.toLowerCase(); } } return "latin1"; } else { return name.toLowerCase(); } } private void prepDrawing() { /* Pop gstates until we can set the needed clip * and transform or until we are at the outer most * gstate. */ while (isOuterGState() == false && (getGState().canSetClip(mLastClip) == false || getGState().mTransform.equals(mLastTransform) == false)) { grestore(); } /* Set the color. This can push the color to the * outer most gsave which is often a good thing. */ getGState().emitPSColor(mLastColor); /* We do not want to change the outermost * transform or clip so if we are at the * outer clip the generate a gsave. */ if (isOuterGState()) { gsave(); getGState().emitTransform(mLastTransform); getGState().emitPSClip(mLastClip); } /* Set the font if we have been asked to. It is * important that the font is set after the * transform in order to get the font size * correct. */ // if (g != null) { // getGState().emitPSFont(g, mLastFont); // } } /** * Return the GState that is currently on top * of the GState stack. There should always be * a GState on top of the stack. If there isn't * then this method will throw an IndexOutOfBounds * exception. */ private GState getGState() { int count = mGStateStack.size(); return (GState) mGStateStack.get(count - 1); } /** * Emit a PostScript gsave command and add a * new GState on to our stack which represents * the printer's gstate stack. */ private void gsave() { GState oldGState = getGState(); mGStateStack.add(new GState(oldGState)); mPSStream.println(GSAVE_STR); } /** * Emit a PostScript grestore command and remove * a GState from our stack which represents the * printer's gstate stack. */ private void grestore() { int count = mGStateStack.size(); mGStateStack.remove(count - 1); mPSStream.println(GRESTORE_STR); } /** * Return true if the current GState is the * outermost GState and therefore should not * be restored. */ private boolean isOuterGState() { return mGStateStack.size() == 1; } /** * A stack of GStates is maintained to model the printer's * gstate stack. Each GState holds information about * the current graphics attributes. */ private class GState{ Color mColor; Shape mClip; Font mFont; AffineTransform mTransform; GState() { mColor = Color.black; mClip = null; mFont = null; mTransform = new AffineTransform(); } GState(GState copyGState) { mColor = copyGState.mColor; mClip = copyGState.mClip; mFont = copyGState.mFont; mTransform = copyGState.mTransform; } boolean canSetClip(Shape clip) { return mClip == null || mClip.equals(clip); } void emitPSClip(Shape clip) { if (clip != null && (mClip == null || mClip.equals(clip) == false)) { String saveFillOp = mFillOpStr; String saveClipOp = mClipOpStr; convertToPSPath(clip.getPathIterator(new AffineTransform())); selectClipPath(); mClip = clip; /* The clip is a shape and has reset the winding rule state */ mClipOpStr = saveFillOp; mFillOpStr = saveFillOp; } } void emitTransform(AffineTransform transform) { if (transform != null && transform.equals(mTransform) == false) { double[] matrix = new double[6]; transform.getMatrix(matrix); mPSStream.println("[" + (float)matrix[0] + " " + (float)matrix[1] + " " + (float)matrix[2] + " " + (float)matrix[3] + " " + (float)matrix[4] + " " + (float)matrix[5] + "] concat"); mTransform = transform; } } void emitPSColor(Color color) { if (color != null && color.equals(mColor) == false) { float[] rgb = color.getRGBColorComponents(null); /* If the color is a gray value then use * setgray. */ if (rgb[0] == rgb[1] && rgb[1] == rgb[2]) { mPSStream.println(rgb[0] + SETGRAY_STR); /* It's not gray so use setrgbcolor. */ } else { mPSStream.println(rgb[0] + " " + rgb[1] + " " + rgb[2] + " " + SETRGBCOLOR_STR); } mColor = color; } } void emitPSFont(int psFontIndex, float fontSize) { mPSStream.println(fontSize + " " + psFontIndex + " " + SetFontName); } } /** * Given a Java2D <code>PathIterator</code> instance, * this method translates that into a PostScript path.. */ void convertToPSPath(PathIterator pathIter) { float[] segment = new float[6]; int segmentType; /* Map the PathIterator's fill rule into the PostScript * fill rule. */ int fillRule; if (pathIter.getWindingRule() == PathIterator.WIND_EVEN_ODD) { fillRule = FILL_EVEN_ODD; } else { fillRule = FILL_WINDING; } beginPath(); setFillMode(fillRule); while (pathIter.isDone() == false) { segmentType = pathIter.currentSegment(segment); switch (segmentType) { case PathIterator.SEG_MOVETO: moveTo(segment[0], segment[1]); break; case PathIterator.SEG_LINETO: lineTo(segment[0], segment[1]); break; /* Convert the quad path to a bezier. */ case PathIterator.SEG_QUADTO: float lastX = getPenX(); float lastY = getPenY(); float c1x = lastX + (segment[0] - lastX) * 2 / 3; float c1y = lastY + (segment[1] - lastY) * 2 / 3; float c2x = segment[2] - (segment[2] - segment[0]) * 2/ 3; float c2y = segment[3] - (segment[3] - segment[1]) * 2/ 3; bezierTo(c1x, c1y, c2x, c2y, segment[2], segment[3]); break; case PathIterator.SEG_CUBICTO: bezierTo(segment[0], segment[1], segment[2], segment[3], segment[4], segment[5]); break; case PathIterator.SEG_CLOSE: closeSubpath(); break; } pathIter.next(); } } /* * Fill the path defined by <code>pathIter</code> * with the specified color. * The path is provided in current user space. */ protected void deviceFill(PathIterator pathIter, Color color, AffineTransform tx, Shape clip) { setTransform(tx); setClip(clip); setColor(color); convertToPSPath(pathIter); /* Specify the path to fill as the clip, this ensures that only * pixels which are inside the path will be filled, which is * what the Java 2D APIs specify */ mPSStream.println(GSAVE_STR); selectClipPath(); fillPath(); mPSStream.println(GRESTORE_STR + " " + NEWPATH_STR); } /* * Run length encode byte array in a form suitable for decoding * by the PS Level 2 filter RunLengthDecode. * Array data to encode is inArr. Encoded data is written to outArr * outArr must be long enough to hold the encoded data but this * can't be known ahead of time. * A safe assumption is to use double the length of the input array. * This is then copied into a new array of the correct length which * is returned. * Algorithm: * Encoding is a lead byte followed by data bytes. * Lead byte of 0->127 indicates leadByte + 1 distinct bytes follow * Lead byte of 129->255 indicates 257 - leadByte is the number of times * the following byte is repeated in the source. * 128 is a special lead byte indicating end of data (EOD) and is * written as the final byte of the returned encoded data. */ private byte[] rlEncode(byte[] inArr) { int inIndex = 0; int outIndex = 0; int startIndex = 0; int runLen = 0; byte[] outArr = new byte[(inArr.length * 2) +2]; while (inIndex < inArr.length) { if (runLen == 0) { startIndex = inIndex++; runLen=1; } while (runLen < 128 && inIndex < inArr.length && inArr[inIndex] == inArr[startIndex]) { runLen++; // count run of same value inIndex++; } if (runLen > 1) { outArr[outIndex++] = (byte)(257 - runLen); outArr[outIndex++] = inArr[startIndex]; runLen = 0; continue; // back to top of while loop. } // if reach here have a run of different values, or at the end. while (runLen < 128 && inIndex < inArr.length && inArr[inIndex] != inArr[inIndex-1]) { runLen++; // count run of different values inIndex++; } outArr[outIndex++] = (byte)(runLen - 1); for (int i = startIndex; i < startIndex+runLen; i++) { outArr[outIndex++] = inArr[i]; } runLen = 0; } outArr[outIndex++] = (byte)128; byte[] encodedData = new byte[outIndex]; System.arraycopy(outArr, 0, encodedData, 0, outIndex); return encodedData; } /* written acc. to Adobe Spec. "Filtered Files: ASCIIEncode Filter", * "PS Language Reference Manual, 2nd edition: Section 3.13" */ private byte[] ascii85Encode(byte[] inArr) { byte[] outArr = new byte[((inArr.length+4) * 5 / 4) + 2]; long p1 = 85; long p2 = p1*p1; long p3 = p1*p2; long p4 = p1*p3; byte pling = '!'; int i = 0; int olen = 0; long val, rem; while (i+3 < inArr.length) { val = ((long)((inArr[i++]&0xff))<<24) + ((long)((inArr[i++]&0xff))<<16) + ((long)((inArr[i++]&0xff))<< 8) + ((long)(inArr[i++]&0xff)); if (val == 0) { outArr[olen++] = 'z'; } else { rem = val; outArr[olen++] = (byte)(rem / p4 + pling); rem = rem % p4; outArr[olen++] = (byte)(rem / p3 + pling); rem = rem % p3; outArr[olen++] = (byte)(rem / p2 + pling); rem = rem % p2; outArr[olen++] = (byte)(rem / p1 + pling); rem = rem % p1; outArr[olen++] = (byte)(rem + pling); } } // input not a multiple of 4 bytes, write partial output. if (i < inArr.length) { int n = inArr.length - i; // n bytes remain to be written val = 0; while (i < inArr.length) { val = (val << 8) + (inArr[i++]&0xff); } int append = 4 - n; while (append-- > 0) { val = val << 8; } byte []c = new byte[5]; rem = val; c[0] = (byte)(rem / p4 + pling); rem = rem % p4; c[1] = (byte)(rem / p3 + pling); rem = rem % p3; c[2] = (byte)(rem / p2 + pling); rem = rem % p2; c[3] = (byte)(rem / p1 + pling); rem = rem % p1; c[4] = (byte)(rem + pling); for (int b = 0; b < n+1 ; b++) { outArr[olen++] = c[b]; } }