static void FillPixelBuffer(Header header, FrameBuffer frameBuffer, Direction dir, Streams streams) { PixelBufferEntry[] cellBuffer = new PixelBufferEntry[frameBuffer.cells.Length]; int pixelMask = 0; int[] read_pixel = new int[4]; int pb_idx = -1; for (int f = 0; f < header.framesPerDir; ++f) { Frame frame = dir.frames[f]; int cell0_x = (frame.box.xMin - dir.box.xMin) / 4; int cell0_y = (frame.box.yMin - dir.box.yMin) / 4; CreateFrameCells(dir.box, frame); // dcc_prepare_frame_cells int buffCellIndex = cell0_x + cell0_y * frameBuffer.nb_cell_w; int frameCellIndex = 0; for (int y = 0; y < frame.nb_cell_h; ++y) { for (int x = 0; x < frame.nb_cell_w; ++x, ++frameCellIndex) { int curr_cell = buffCellIndex + x; if (cellBuffer[curr_cell].val != null) { if (streams.equalCell != null && streams.equalCell.ReadBool() != 0) { continue; } pixelMask = streams.pixelMask.ReadLessThanByte(4); } else { pixelMask = 0x0f; } read_pixel[0] = read_pixel[1] = read_pixel[2] = read_pixel[3] = 0; int last_pixel = 0; int nb_pix = nb_pix_table[pixelMask]; int encodingType = 0; if (nb_pix != 0 && streams.encodingType != null) { encodingType = streams.encodingType.ReadBool(); } int decoded_pix = 0; for (int i = 0; i < nb_pix; i++) { if (encodingType != 0) { read_pixel[i] = streams.rawPixel.ReadByte(); } else { read_pixel[i] = last_pixel; int pix_displ = streams.pixelCode.ReadLessThanByte(4); read_pixel[i] += pix_displ; while (pix_displ == 15) { pix_displ = streams.pixelCode.ReadLessThanByte(4); read_pixel[i] += pix_displ; } } if (read_pixel[i] == last_pixel) { read_pixel[i] = 0; // discard this pixel break; // stop the decoding of pixels } else { last_pixel = read_pixel[i]; decoded_pix++; } } // we have the 4 pixels code for the new entry in pixel_buffer PixelBufferEntry old_entry = cellBuffer[curr_cell]; pb_idx++; var newEntry = new PixelBufferEntry(); newEntry.val = new byte[4]; int curr_idx = decoded_pix - 1; for (int i = 0; i < 4; i++) { if ((pixelMask & (1 << i)) != 0) { if (curr_idx >= 0) // if stack is not empty, pop it { newEntry.val[i] = (byte)read_pixel[curr_idx--]; } } else { newEntry.val[i] = old_entry.val[i]; } } newEntry.frame = f; newEntry.frameCellIndex = frameCellIndex; pixelBuffer[pb_idx] = newEntry; cellBuffer[curr_cell] = newEntry; } buffCellIndex += frameBuffer.nb_cell_w; } } for (int i = 0; i <= pb_idx; i++) { for (int x = 0; x < 4; x++) { int y = pixelBuffer[i].val[x]; pixelBuffer[i].val[x] = dir.pixel_values[y]; } } pixelBuffer[pb_idx + 1].frame = -1; }
static void MakeFrames(Header header, Direction dir, FrameBuffer frameBuffer, Streams streams, List <Texture2D> textures, Sprite[] sprites) { const int padding = 2; int textureWidth = Mathf.NextPowerOfTwo((dir.box.width + padding) * header.framesPerDir); int textureHeight = Mathf.NextPowerOfTwo(dir.box.height + padding); textureWidth = Mathf.Min(1024, textureWidth); var packer = new TexturePacker(textureWidth, textureHeight); Texture2D texture = null; Color32[] pixels = null; for (int c = 0; c < frameBuffer.cells.Length; c++) { frameBuffer.cells[c].w = -1; frameBuffer.cells[c].h = -1; } int pb_idx = 0; PixelBufferEntry pbe = pixelBuffer[pb_idx]; for (int f = 0; f < header.framesPerDir; f++) { Frame frame = dir.frames[f]; var pack = packer.put(dir.box.width + padding, dir.box.height + padding); if (pack.newTexture) { if (texture != null) { texture.SetPixels32(pixels); texture.Apply(false); } texture = new Texture2D(textureWidth, textureHeight, TextureFormat.RGBA32, false); pixels = new Color32[textureWidth * textureHeight]; textures.Add(texture); } frame.texture = texture; frame.texturePixels = pixels; frame.textureX = pack.x; frame.textureY = pack.y; var textureRect = new Rect(frame.textureX, frame.textureY, dir.box.width, dir.box.height); var pivot = new Vector2(-dir.box.xMin / (float)dir.box.width, dir.box.yMax / (float)dir.box.height); sprites[f] = Sprite.Create(texture, textureRect, pivot, Iso.pixelsPerUnit, extrude: 0, meshType: SpriteMeshType.FullRect); int nb_cell = frame.nb_cell_w * frame.nb_cell_h; for (int c = 0; c < nb_cell; c++) { Cell cell = frame.cells[c]; // buffer cell int cell_x = cell.x0 >> 2; int cell_y = cell.y0 >> 2; int cell_idx = cell_x + (cell_y * frameBuffer.nb_cell_w); // equal cell checks if ((pbe.frame != f) || (pbe.frameCellIndex != c)) { // this buffer cell have an equalcell bit set to 1 so copy the frame cell Cell buff_cell = frameBuffer.cells[cell_idx]; if (cell.w == buff_cell.w && cell.h == buff_cell.h) { Frame refFrame = dir.frames[f - 1]; int textureY = refFrame.textureY + dir.box.height - buff_cell.y0; int textureX = refFrame.textureX + buff_cell.x0; int srcOffset = textureWidth * textureY + textureX; textureY = frame.textureY + dir.box.height - cell.y0; textureX = frame.textureX + cell.x0; int dstOffset = textureWidth * textureY + textureX; for (int y = 0; y < cell.h; y++) { System.Array.Copy(refFrame.texturePixels, srcOffset, frame.texturePixels, dstOffset, cell.w); srcOffset -= textureWidth; dstOffset -= textureWidth; } } } else { // fill the frame cell with pixels if (pbe.val[0] == pbe.val[1]) { // fill FRAME cell to color val[0] //clear_to_color(cell->bmp, pbe->val[0]); } else { int nb_bit; if (pbe.val[1] == pbe.val[2]) { nb_bit = 1; } else { nb_bit = 2; } // fill FRAME cell with pixels int textureY = frame.textureY + dir.box.height - cell.y0; int textureX = frame.textureX + cell.x0; int offset = textureWidth * textureY + textureX; for (int y = 0; y < cell.h; ++y) { for (int x = 0; x < cell.w; ++x) { int pix = streams.pixelCode.ReadLessThanByte(nb_bit); Color32 color = Palette.palette[pbe.val[pix]]; frame.texturePixels[offset + x] = color; } offset -= textureWidth; } } // next pixelbuffer entry pb_idx++; pbe = pixelBuffer[pb_idx]; } // for the buffer cell that was used by this frame cell, // save the width & size of the current frame cell // (needed for further tests about equalcell) // and save its origin, for further copy when equalcell frameBuffer.cells[cell_idx] = cell; } } if (texture != null) { texture.SetPixels32(pixels); texture.Apply(false); } }
private void FillPixelBuffer(BitMuncher pcd, BitMuncher ec, BitMuncher pm, BitMuncher et, BitMuncher rp) { UInt32 lastPixel = 0; var maxCellX = Frames.Sum(x => x.HorizontalCellCount); var maxCellY = Frames.Sum(x => x.VerticalCellCount); PixelBuffer = new PixelBufferEntry[maxCellX * maxCellY]; for (var i = 0; i < maxCellX * maxCellY; i++) { PixelBuffer[i] = new PixelBufferEntry { Frame = -1, FrameCellIndex = -1, Value = new byte[4] } } ; var cellBuffer = new PixelBufferEntry[HorizontalCellCount * VerticalCellCount]; var frameIndex = -1; var pbIndex = -1; UInt32 pixelMask = 0x00; foreach (var frame in Frames) { frameIndex++; var originCellX = (frame.Box.Left - Box.Left) / 4; var originCellY = (frame.Box.Top - Box.Top) / 4; var frameCellIndex = 0; for (var cellY = 0; cellY < frame.VerticalCellCount; cellY++) { var currentCellY = cellY + originCellY; for (var cellX = 0; cellX < frame.HorizontalCellCount; cellX++, frameCellIndex++) { var currentCell = originCellX + cellX + (currentCellY * HorizontalCellCount); var nextCell = false; var tmp = 0; if (cellBuffer[currentCell] != null) { if (EqualCellsBitstreamSize > 0) { tmp = (int)ec.GetBit(); } else { tmp = 0; } if (tmp == 0) { pixelMask = pm.GetBits(4); } else { nextCell = true; } } else { pixelMask = 0x0F; } if (nextCell) { continue; } // Decode the pixels var pixelStack = new UInt32[4]; lastPixel = 0; int numberOfPixelBits = pixelMaskLookup[pixelMask]; int encodingType = 0; if ((numberOfPixelBits != 0) && (EncodingTypeBitsreamSize > 0)) { encodingType = (int)et.GetBit(); } else { encodingType = 0; } int decodedPixel = 0; for (int i = 0; i < numberOfPixelBits; i++) { if (encodingType != 0) { pixelStack[i] = rp.GetBits(8); } else { pixelStack[i] = lastPixel; var pixelDisplacement = pcd.GetBits(4); pixelStack[i] += pixelDisplacement; while (pixelDisplacement == 15) { pixelDisplacement = pcd.GetBits(4); pixelStack[i] += pixelDisplacement; } } if (pixelStack[i] == lastPixel) { pixelStack[i] = 0; i = numberOfPixelBits; // Just break here.... } else { lastPixel = pixelStack[i]; decodedPixel++; } } var oldEntry = cellBuffer[currentCell]; pbIndex++; var newEntry = PixelBuffer[pbIndex]; var curIdx = decodedPixel - 1; for (int i = 0; i < 4; i++) { if ((pixelMask & (1 << i)) != 0) { if (curIdx >= 0) { newEntry.Value[i] = (byte)pixelStack[curIdx--]; } else { newEntry.Value[i] = 0; } } else { newEntry.Value[i] = oldEntry.Value[i]; } } cellBuffer[currentCell] = newEntry; newEntry.Frame = frameIndex; newEntry.FrameCellIndex = cellX + (cellY * frame.HorizontalCellCount); } } } // Convert the palette entry index into actual palette entries for (var i = 0; i <= pbIndex; i++) { for (var x = 0; x < 4; x++) { PixelBuffer[i].Value[x] = PaletteEntries[PixelBuffer[i].Value[x]]; } } }