private void setupBlobs(DataBlob metadata) { C1 = new DataBlob(); C2 = new DataBlob(); C3 = new DataBlob(); V2 = new DataBlob(); V3 = new DataBlob(); C1.type = C2.type = C3.type = DataBlob.Type.Channels; V2.type = V3.type = DataBlob.Type.Vectors; //import metadata onto channels C1.imageWidth = C2.imageWidth = C3.imageWidth = metadata.imageWidth; C1.imageHeight = C2.imageHeight = C3.imageHeight = metadata.imageHeight; C1.channelWidth = C2.channelWidth = C3.channelWidth = metadata.channelWidth; C1.channelHeight = C2.channelHeight = C3.channelHeight = metadata.channelHeight; C1.quantizeQuality = C2.quantizeQuality = C3.quantizeQuality = metadata.quantizeQuality; C1.samplingMode = C2.samplingMode = C3.samplingMode = metadata.samplingMode; Chunker c = new Chunker(8, metadata.channelWidth, metadata.channelHeight, metadata.channelWidth, 1); V2.imageWidth = V3.imageWidth = metadata.imageWidth; V2.imageHeight = V3.imageHeight = metadata.imageHeight; V2.channelWidth = V3.channelWidth = c.getChunksWide(); V2.channelHeight = V3.channelHeight = c.getChunksHigh(); V2.quantizeQuality = V3.quantizeQuality = metadata.quantizeQuality; V2.samplingMode = V3.samplingMode = metadata.samplingMode; //Allocate space for incoming data C1.channels = new byte[3][]; C2.channels = new byte[3][]; C3.channels = new byte[3][]; V2.channels = new byte[3][]; V3.channels = new byte[3][]; int cMajor = C1.channelWidth * C1.channelHeight; Size sizeMinor = Subsample.getPaddedCbCrSize(new Size(C1.channelWidth, C1.channelHeight), C1.samplingMode); int cMinor = sizeMinor.Width * sizeMinor.Height; C1.channels[0] = new byte[cMajor]; C2.channels[0] = new byte[cMajor]; C3.channels[0] = new byte[cMajor]; C1.channels[1] = new byte[cMinor]; C2.channels[1] = new byte[cMinor]; C3.channels[1] = new byte[cMinor]; C1.channels[2] = new byte[cMinor]; C2.channels[2] = new byte[cMinor]; C3.channels[2] = new byte[cMinor]; cMajor = V2.channelWidth * V2.channelHeight; sizeMinor = Subsample.getCbCrSize(new Size(V2.channelWidth, V2.channelHeight), V2.samplingMode); cMinor = sizeMinor.Width * sizeMinor.Height; V2.channels[0] = new byte[cMajor]; V3.channels[0] = new byte[cMajor]; V2.channels[1] = new byte[cMinor]; V3.channels[1] = new byte[cMinor]; V2.channels[2] = new byte[cMinor]; V3.channels[2] = new byte[cMinor]; }
private void padChannels() { //pad the size Size ySize = new Size(state.channelWidth, state.channelHeight); Size brOldSize = Subsample.deduceCbCrSize(state); Size brNewSize = Subsample.getPaddedCbCrSize(ySize, state.samplingMode); if (ySize.Width % 8 != 0) { ySize.Width += 8 - (ySize.Width % 8); } if (ySize.Height % 8 != 0) { ySize.Height += 8 - (ySize.Height % 8); } //create padded container byte[][] newChannels = new byte[3][]; newChannels[0] = new byte[ySize.Width * ySize.Height]; newChannels[1] = new byte[brNewSize.Width * brNewSize.Height]; newChannels[2] = new byte[newChannels[1].Length]; //copy array into larger container for (int y = 0; y < state.channelHeight; y++) { Array.Copy(state.channels[0], y * state.channelWidth, newChannels[0], y * ySize.Width, state.channelWidth); } for (int y = 0; y < brOldSize.Height; y++) { Array.Copy(state.channels[1], y * brOldSize.Width, newChannels[1], y * brNewSize.Width, brOldSize.Width); Array.Copy(state.channels[2], y * brOldSize.Width, newChannels[2], y * brNewSize.Width, brOldSize.Width); for (int x = brOldSize.Width; x < brNewSize.Width; x++) { newChannels[1][y * brNewSize.Width + x] = 127; newChannels[2][y * brNewSize.Width + x] = 127; } } //update state state.channelWidth = ySize.Width; state.channelHeight = ySize.Height; state.channels = newChannels; }
protected override void clean() { base.clean(); if (state == null || state.channels == null) { return; } if (!isInverse) { state.quantizeQuality = properties["quality"].nValue; } generateQTables(state.quantizeQuality); padChannels(); Chunker c = new Chunker(chunkSize, state.channelWidth, state.channelHeight, state.channelWidth, 1); byte[] data = new byte[chunkSize * chunkSize]; for (int i = 0; i < c.getNumChunks(); i++) { c.getBlock(state.channels[0], data, i); data = isInverse ? doIDCT(data, quantizationY) : doDCT(data, quantizationY); c.setBlock(state.channels[0], data, i); } Size tempS = Subsample.getPaddedCbCrSize(new Size(state.channelWidth, state.channelHeight), state.samplingMode); c = new Chunker(chunkSize, tempS.Width, tempS.Height, tempS.Width, 1); for (int i = 0; i < c.getNumChunks(); i++) { c.getBlock(state.channels[1], data, i); data = isInverse ? doIDCT(data, quantizationC) : doDCT(data, quantizationC); c.setBlock(state.channels[1], data, i); c.getBlock(state.channels[2], data, i); data = isInverse ? doIDCT(data, quantizationC) : doDCT(data, quantizationC); c.setBlock(state.channels[2], data, i); } }
private void open(object sender, EventArgs e) { soil(); clean(); state = new DataBlob(); state.type = DataBlob.Type.Channels; state.channels = new byte[3][]; using (Stream stream = new FileStream(inPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader reader = new BinaryReader(stream, Encoding.Default)) { state.imageWidth = reader.ReadUInt16(); state.imageHeight = reader.ReadUInt16(); state.channelWidth = reader.ReadUInt16(); state.channelHeight = reader.ReadUInt16(); state.quantizeQuality = reader.ReadByte(); state.samplingMode = (DataBlob.Samples)reader.ReadByte(); state.channels[0] = new byte[state.channelWidth * state.channelHeight]; byte[] data = new byte[64]; byte count, val; //====================== //===== Y Channel ====== //====================== Chunker c = new Chunker(8, state.channelWidth, state.channelHeight, state.channelWidth, 1); var indexer = Chunker.zigZag8Index(); for (int iChunk = 0; iChunk < c.getNumChunks(); iChunk++) { for (int iPixel = 0; iPixel < 64;) { val = reader.ReadByte(); if (val != rleToken) { data[iPixel++] = val; } else { count = reader.ReadByte(); val = reader.ReadByte(); while (count > 0) { data[iPixel++] = val; count--; } } } c.setZigZag8Block(state.channels[0], data, iChunk); } //=========================== //===== Cr, Cb Channels ===== //=========================== Size len = Subsample.getPaddedCbCrSize(new Size(state.channelWidth, state.channelHeight), state.samplingMode); state.channels[1] = new byte[len.Width * len.Height]; state.channels[2] = new byte[state.channels[1].Length]; c = new Chunker(8, len.Width, len.Height, len.Width, 1); indexer = Chunker.zigZag8Index(); for (int channel = 1; channel < state.channels.Length; channel++) { for (int iChunk = 0; iChunk < c.getNumChunks(); iChunk++) { for (int iPixel = 0; iPixel < 64;) { val = reader.ReadByte(); if (val != rleToken) { data[iPixel++] = val; } else { count = reader.ReadByte(); val = reader.ReadByte(); while (count > 0) { data[iPixel++] = val; count--; } } } c.setZigZag8Block(state.channels[channel], data, iChunk); } } } } //close file }