<commit_before>﻿using LibPixelPet;

namespace PixelPet.CLI.Commands {
	internal class SerializeTilesetCmd : CliCommand {
		public SerializeTilesetCmd()
			: base("Serialize-Tileset",
				new Parameter("append", "a", false),
				new Parameter("color-offset", "o", false, new ParameterValue("value", "0"))
			) { }

		protected override void Run(Workbench workbench, ILogger logger) {
			bool append = FindNamedParameter("--append").IsPresent;
			long colorOffset = FindNamedParameter("--color-offset").Values[0].ToInt64();

			ColorFormat fmt = workbench.Tileset.ColorFormat;
			int bpp = fmt.Bits;     // bits per pixel
			int ppb = 8 / bpp;      // pixels per byte

			int pi;                 // pixel index in current byte
			int b;                  // current byte
			int b2;                 // current byte 2
			long co;                // color + offset

			if (append) {
				workbench.Stream.Position = workbench.Stream.Length;
			} else {
				workbench.Stream.SetLength(0);
			}

			foreach (Tile tile in workbench.Tileset) {
				switch (workbench.TilemapFormat.BitmapEncoding) {
				case BitmapEncoding.GameBoyAdvance:
					SerializeNormal(tile);
					break;
				case BitmapEncoding.GameBoy:
					SerializeGameBoy(tile);
					break;
				}
			}

			logger?.Log("Serialized " + workbench.Tileset.Count + " tiles.", LogLevel.Information);

			void SerializeNormal(Tile tile) {
				pi = 0;
				b  = 0;
				foreach (int c in tile.EnumerateTile()) {
					co = c + colorOffset;
					// Add pixel to current byte.
					b |= (int)(co << (pi * bpp));

					if (++pi >= ppb) {
						// Write byte to stream if it's finished.
						workbench.Stream.WriteByte((byte)b);
						b  = 0;
						pi = 0;
					}
				}
				if (pi > 0) {
					// Write remainder byte to stream.
					workbench.Stream.WriteByte((byte)b);
				}
			}

			void SerializeGameBoy(Tile tile) {
				pi = 0;
				b  = 0;
				b2 = 0;
				foreach (int c in tile.EnumerateTile()) {
					co = c + colorOffset;
					// Add pixel to current byte.
					b  |= (int)((co & 0x1) >> 0 << (7 - pi));
					b2 |= (int)((co & 0x2) >> 1 << (7 - pi));
					
					if (++pi >= 2 * ppb) {
						// Write byte to stream if it's finished.
						workbench.Stream.WriteByte((byte)b);
						workbench.Stream.WriteByte((byte)b2);
						b  = 0;
						b2 = 0;
						pi = 0;
					}
				}
				if (pi > 0) {
					// Write remainder bytes to stream.
					workbench.Stream.WriteByte((byte)b);
					workbench.Stream.WriteByte((byte)b2);
				}
			}
		}
	}
}
<commit_msg>Fix Serialize-Tileset when the tileset is not indexed.<commit_after>﻿using LibPixelPet;

namespace PixelPet.CLI.Commands {
	internal class SerializeTilesetCmd : CliCommand {
		public SerializeTilesetCmd()
			: base("Serialize-Tileset",
				new Parameter("append", "a", false),
				new Parameter("color-offset", "o", false, new ParameterValue("value", "0"))
			) { }

		protected override void Run(Workbench workbench, ILogger logger) {
			bool append = FindNamedParameter("--append").IsPresent;
			long colorOffset = FindNamedParameter("--color-offset").Values[0].ToInt64();

			ColorFormat fmt = workbench.Tileset.ColorFormat;
			int bpp = fmt.Bits;     // bits per pixel
			int ppb = 8 / bpp;      // pixels per byte

			int pi;                 // pixel index in current byte
			int b;                  // current byte
			int b2;                 // current byte 2
			long co;                // color + offset

			if (append) {
				workbench.Stream.Position = workbench.Stream.Length;
			} else {
				workbench.Stream.SetLength(0);
			}

			foreach (Tile tile in workbench.Tileset) {
				switch (workbench.TilemapFormat.BitmapEncoding) {
				case BitmapEncoding.GameBoyAdvance:
					SerializeNormal(tile);
					break;
				case BitmapEncoding.GameBoy:
					SerializeGameBoy(tile);
					break;
				}
			}

			logger?.Log("Serialized " + workbench.Tileset.Count + " tiles.", LogLevel.Information);

			void SerializeNormal(Tile tile) {
				pi = 0;
				b  = 0;
				foreach (int c in tile.EnumerateTile()) {
					co = c + colorOffset;

					if (bpp > 4) {
						for (int bi = 0; bi < bpp; bi += 8) {
							workbench.Stream.WriteByte((byte)(co >> bi));
						}
					} else {
						// Add pixel to current byte.
						b |= (int)(co << (pi * bpp));

						if (++pi >= ppb) {
							// Write byte to stream if it's finished.
							workbench.Stream.WriteByte((byte)b);
							b = 0;
							pi = 0;
						}
					}
				}
				if (pi > 0) {
					// Write remainder byte to stream.
					workbench.Stream.WriteByte((byte)b);
				}
			}

			void SerializeGameBoy(Tile tile) {
				pi = 0;
				b  = 0;
				b2 = 0;
				foreach (int c in tile.EnumerateTile()) {
					co = c + colorOffset;
					// Add pixel to current byte.
					b  |= (int)((co & 0x1) >> 0 << (7 - pi));
					b2 |= (int)((co & 0x2) >> 1 << (7 - pi));
					
					if (++pi >= 2 * ppb) {
						// Write byte to stream if it's finished.
						workbench.Stream.WriteByte((byte)b);
						workbench.Stream.WriteByte((byte)b2);
						b  = 0;
						b2 = 0;
						pi = 0;
					}
				}
				if (pi > 0) {
					// Write remainder bytes to stream.
					workbench.Stream.WriteByte((byte)b);
					workbench.Stream.WriteByte((byte)b2);
				}
			}
		}
	}
}

{'fraction_non_alphanumeric': 0.13858328508010037, 'fraction_numerical': 0.013703918162516888, 'mean_word_length': 2.1425106124924196, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1359250', 'n_tokens_mistral': 2296, 'n_tokens_neox': 1701, 'n_words': 435}