/// <summary> /// /// </summary> /// <param name="image"></param> /// <param name="quality">Quality of the image. 0 to 100 and from bad image quality, high compression to good image quality low compression</param> /// <param name="output"></param> /// <param name="comment"></param> public JpegEncoder(Image image, Stream output, String comment, int quality = 80) { this.quality = quality; // Getting picture information It takes the Width, Height and RGB scans of the image. this.JpegObj = new JpegInfo(image, comment); this.imageHeight = this.JpegObj.ImageHeight; this.imageWidth = this.JpegObj.ImageWidth; this.output = new BufferedStream(output); this.output.SetLength(0); this.dct = new DCT(this.quality); this.huffman = new Huffman(); }
private int[] GetCoeff(int MinBlockWidth, int MinBlockHeight) { float[][] dctArray1 = ArrayHelper.CreateJagged <float>(8, 8); double[][] dctArray2 = ArrayHelper.CreateJagged <double>(8, 8); int[] dctArray3 = new int[8 * 8]; int[] coeff; float[][] inputArray; int i, j, r, c, a, b, comp; int ypos, Width, Height, xblockoffset, yblockoffset; int xpos = 0; int shuffledIndex = 0; int coeffCount = 0; // westfeld // Before we enter these loops, we initialise the coeff for steganography here: for (r = 0; r < MinBlockHeight; r++) { for (c = 0; c < MinBlockWidth; c++) { for (comp = 0; comp < JpegInfo.NumberOfComponents; comp++) { for (i = 0; i < this.JpegObj.VsampFactor[comp]; i++) { for (j = 0; j < this.JpegObj.HsampFactor[comp]; j++) { coeffCount += 64; } } } } } coeff = new int[coeffCount]; logger.Info("DCT/quantisation starts"); logger.Info(this.imageWidth + " x " + this.imageHeight); for (r = 0; r < MinBlockHeight; r++) { for (c = 0; c < MinBlockWidth; c++) { xpos = c * 8; ypos = r * 8; for (comp = 0; comp < JpegInfo.NumberOfComponents; comp++) { Width = this.JpegObj.BlockWidth[comp]; Height = this.JpegObj.BlockHeight[comp]; inputArray = this.JpegObj.Components[comp]; var maxa = imageHeight / 2 * this.JpegObj.VsampFactor[comp] - 1; var maxb = imageWidth / 2 * this.JpegObj.HsampFactor[comp] - 1; for (i = 0; i < this.JpegObj.VsampFactor[comp]; i++) { for (j = 0; j < this.JpegObj.HsampFactor[comp]; j++) { xblockoffset = j * 8; yblockoffset = i * 8; for (a = 0; a < 8; a++) { for (b = 0; b < 8; b++) { // I believe this is where the dirty line at // the bottom of the image is // coming from. I need to do a check here to // make sure I'm not reading past // image data. // This seems to not be a big issue right // now. (04/04/98) // westfeld - dirty line fixed, Jun 6 2000 int ia = Math.Min(ypos * this.JpegObj.VsampFactor[comp] + yblockoffset + a, maxa); int ib = Math.Min(xpos * this.JpegObj.HsampFactor[comp] + xblockoffset + b, maxb); // dctArray1[a][b] = inputArray[ypos + // yblockoffset + a][xpos + xblockoffset + // b]; dctArray1[a][b] = inputArray[ia][ib]; } } // The following code commented out because on some // images this technique // results in poor right and bottom borders. // if ((!JpegObj.lastColumnIsDummy[comp] || c < // Width - 1) && (!JpegObj.lastRowIsDummy[comp] || r // < Height - 1)) { dctArray2 = DCT.ForwardDCT(dctArray1); dctArray3 = this.dct.QuantizeBlock(dctArray2, this.JpegObj.QtableNumber[comp]); // } // else { // zeroArray[0] = dctArray3[0]; // zeroArray[0] = lastDCvalue[comp]; // dctArray3 = zeroArray; // } // westfeld // For steganography, all dct // coefficients are collected in // coeff[] first. We do not encode // any Huffman Blocks here (we'll do // this later). Array.Copy(dctArray3, 0, coeff, shuffledIndex, 64); shuffledIndex += 64; } } } } } return(coeff); }