internal static string GenerateProgramFromImage(string path, string name, PrimeParameters settings) { const int width = 320, height = 240; var mode = settings.GetSetting("ImageMethod", ImageProcessingMode.DimgrobPieces); var img = ResizeImage(Image.FromFile(path, true), width, height, mode == ImageProcessingMode.Pixels || mode == ImageProcessingMode.DimgrobPieces, settings); const string defaultColor = "000000"; // RRGGBB var p = new StringBuilder("EXPORT " + name + "()"); p.Append("\nBEGIN\n"); switch (mode) { case ImageProcessingMode.Pixels: p.Append("RECT(#" + defaultColor + "h);\n"); const int totalBytesPixels = width * height * 3; var bmpDataPixels = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); var rgbValuesPixels = new byte[totalBytesPixels]; // Copy the RGB values into the array Marshal.Copy(bmpDataPixels.Scan0, rgbValuesPixels, 0, totalBytesPixels); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { var c = GetColor(ref rgbValuesPixels, x, y, width); if (c != defaultColor) { p.Append(String.Format("PIXON_P({0},{1},#{2}h);\n", x, y, c)); } } } img.UnlockBits(bmpDataPixels); p.Append("WAIT;END;"); break; case ImageProcessingMode.DimgrobPieces: const int totalBytes = width * height * 2; var bmpData = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format16bppArgb1555); var rgbValues = new byte[totalBytes]; // Copy the RGB values into the array. Marshal.Copy(bmpData.Scan0, rgbValues, 0, totalBytes); var dimGrobParts = new List <String>(); var optimizeBlack = settings.GetFlag("ImageMethodDimgrobOptimizeBlacks"); for (var y = 0; y < height; y++) { for (var x = 0; x <= (width * 2) - 8; x += 8) { var r = (y * 640) + x; dimGrobParts.Add(GetDimGrobPiece(ref rgbValues, r, optimizeBlack)); } } img.UnlockBits(bmpData); // Create the definitions const int rows = 4; var arr = dimGrobParts.ToArray(); try { var lines = new Dictionary <String, List <String> >(); for (var i = 0; i <= height - rows; i += rows) { var c = "DIMGROB_P(G1,320," + rows + ",{" + String.Join(",", arr, i * 80, 320) + "});"; if (!lines.ContainsKey(c)) { lines.Add(c, new List <String>()); } lines[c].Add("BLIT_P(G0,0," + i + "," + 320 + "," + (i + rows) + ",G1,0,0,320," + rows + ");"); } var optimizeSimilar = settings.GetFlag("ImageMethodDimgrobOptimizeSimilar"); foreach (var t in lines) { if (optimizeSimilar) { p.AppendLine(t.Key); } foreach (var l in t.Value) { if (!optimizeSimilar) { p.AppendLine(t.Key); } p.AppendLine(l); } } } catch { } p.Append("WAIT;END;"); break; case ImageProcessingMode.Icon: p.Append("blit_p(" + (width - img.Width / 2) + "," + (height - img.Height / 2) + ",\"img\");\nWAIT;END;\nICON img "); var tmp = Path.GetTempFileName(); var pngCodec = ImageCodecInfo.GetImageEncoders().FirstOrDefault(codec => codec.FormatID.Equals(ImageFormat.Png.Guid)); // //Bitmap bitmap1 = new Bitmap(1, 1); //EncoderParameters paramList = bitmap1.GetEncoderParameterList(pngCodec.Clsid); // if (pngCodec != null) { var parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 4L); //parameters.Param[1] = new EncoderParameter(Encoder., 1); img.Save(tmp, pngCodec, parameters); } else { img.Save(tmp, ImageFormat.Png); } p.Append(BitConverter.ToString(File.ReadAllBytes(tmp)).Replace("-", string.Empty) + ";"); break; } return(p.ToString()); }
/*public static string ApplyCodeRefactoring(string programCode, params RefactorFlag[] flags) * { * IEnumerable<KeyValuePair<string, object>> p; * * foreach (var f in flags) * { * switch (f) * { * case RefactorFlag.RemoveComments: * break; * } * } * * return ApplyCodeRefactoring(programCode, new PrimeParameters(p)); * }*/ public static string ApplyCodeRefactoring(string programCode, PrimeParameters programParameters) { var regexStrings = new Regex(programParameters.GetValue("RegexStrings")); var regexComments = new Regex(programParameters.GetValue("RegexComments")); var operators = programParameters.GetValue("RegexOperators"); var regexOperators = new Regex(operators); // Encode strings and comments programCode = regexStrings.Replace(programCode, EncodeElement); programCode = regexComments.Replace(programCode, programParameters.GetFlag("RemoveComments") ? (m => String.Empty) : (MatchEvaluator)EncodeElement); if (programParameters.GetFlag("CompressSpaces")) { var o = new StringBuilder(); var removeLineBreaks = programParameters.GetFlag("CompressSpacesMore"); var extractedOperators = Regex.Unescape(operators.Replace(@"\s", "") .Substring(0, operators.Length - (operators.EndsWith("])") ? 3 : 1)) .Substring(operators.StartsWith("([") ? 2 : 0)); foreach (var l in programCode.Replace(Environment.NewLine, removeLineBreaks?" ":"\n") .Replace("\r", String.Empty) .Replace(" ", " ") .Replace(" ", " ") .Replace(" ", " ") .Replace(" ", " ") .Replace(" ", " ") .Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var line = l.Trim(new[] { ' ', '\t' }); // Spaces near operators foreach (var c in extractedOperators) { var nline = line; do { line = nline; nline = line.Replace(" " + c, String.Empty + c).Replace(c + " ", String.Empty + c); } while (line.CompareTo(nline) != 0); } o.Append(line); if (!String.IsNullOrEmpty(line) && !line.EndsWith(";")) { o.Append(removeLineBreaks?' ':'\n'); } } programCode = o.ToString(); //tmp = regexOperators.Replace(tmp, m => m.Value.Trim()); } if (programParameters.GetFlag("ObfuscateVariables")) { // List variables var variables = new List <String>(); foreach (Match l in Regex.Matches(programCode, programParameters.GetValue("RegexLocalVariables"), RegexOptions.IgnoreCase)) { foreach (var v in l.Groups["vars"].Value.Split(new[] { ',' })) { var v1 = v.Replace(" ", String.Empty).Replace(":=", "=").Split(new[] { '=' }, 2)[0].Trim(); if (v1.Length <= 2 || v1.Contains("#")) { continue; } if (!variables.Contains(v1)) { variables.Add(v1); } } } if (variables.Count > 0) { // Replacement variables variables.Sort((x, y) => y.Length.CompareTo(x.Length)); var replacements = new Dictionary <String, String>(); var v1 = programParameters.GetValue("VariableRefactoringStartingSeed"); foreach (var v in variables) { var replacement = new StringBuilder(v1); while (variables.Contains(replacement.ToString()) || replacements.ContainsValue(replacement.ToString())) { // Advance last number Next(ref replacement); } replacements.Add(v, replacement.ToString()); } // Do the replacement var final = new StringBuilder(); var regexEncodedPlain = new Regex("(" + Regex.Escape(EncodePrefix) + programParameters.GetValue("RegexBase64") + Regex.Escape(EncodePostfix) + ")"); foreach (var l in regexEncodedPlain.Split(programCode)) { if (l.StartsWith(EncodePrefix) && l.EndsWith(EncodePostfix)) { final.Append(l); } else { foreach (var r in regexOperators.Split(l)) { var append = true; if (r.Length > 0) { foreach (var replace in replacements) { if (r == replace.Key) { final.Append(replace.Value); append = false; break; } } } if (append) { final.Append(r); } } } } programCode = final.ToString(); } } // Restore string and comments again var regexEncoded = new Regex(Regex.Escape(EncodePrefix) + "(?<data>" + programParameters.GetValue("RegexBase64") + ")" + Regex.Escape(EncodePostfix)); return(regexEncoded.Replace(programCode, DecodeElement)); }
/// <summary> /// Parses the data inside a file to be used later /// </summary> /// <param name="path">Input file, including the extension to detect the format</param> /// <param name="settings">Parameters</param> public PrimeProgramFile(string path, PrimeParameters settings = null) { IsValid = false; IsConversion = false; Name = Path.GetFileNameWithoutExtension(path); Data = new byte[0]; switch (Path.GetExtension(path).ToLower()) { case ".txt": // Find "begin" var tmp = File.ReadAllBytes(path); foreach (var encoding in new[] { Encoding.Unicode, Encoding.BigEndianUnicode, null }) { if (CheckEncodingAndSetData(tmp, encoding)) { // Remove signature if (Data.Length > 1 && Data[0] == 0xff && Data[1] == 0xfe) { for (int i = 0; i < Data.Length - 2; i++) { Data[i] = Data[i + 2]; } Data[Data.Length - 2] = 0x00; Data[Data.Length - 1] = 0x00; } IsValid = true; break; } } break; case ".bmp": case ".jpg": case ".jpeg": case ".png": case ".gif": try { // Generate a script that displays the image Data = Encoding.Unicode.GetBytes(Utilities.GenerateProgramFromImage(path, SafeName, settings)); IsValid = true; IsConversion = true; } catch { } break; case ".c8": try { // Generate a script that includes the chip8 emulator Data = Encoding.Unicode.GetBytes(Resources.chip8.Replace("%program%", Utilities.GenerateByteListFromFile(path)).Replace("%name%", Name)); IsValid = true; IsConversion = true; } catch { } break; case null: break; default: var b = File.ReadAllBytes(path); if (b.Length >= 19) { var universalMode = false; if (b[0] == 0xFF && b[1] == 0xFE) { // Plain file with Unicode flag on front Data = b.SubArray(2, b.Length - 2); IsValid = true; IsConversion = true; break; } else { for (var i = 1; i <= 7; i++) { if (b[i] != 0x00) // Special case where b[4]==0x01 { universalMode = true; break; } } } if (universalMode) // Reads from the last byte. This will ignore any header { var finish = b.Length - 1; // Look for the finish for (; finish > 2; finish -= 2) { if (b[finish] == 0x00 && b[finish - 1] == 0x00) { finish--; break; } } var start = finish - 1; // Look for the start for (; start > 2; start -= 2) { if (b[start] == 0x00 && b[start - 1] == 0x00) { start++; IsValid = true; break; } } if (IsValid) { // Clean headers foreach (var h in new[] { new[] { 0xfe, 0xa9, 0x1, 0x0 } }) { var f = start + h.Length; var m = 0; for (var t = start; t < f; t++) { if (b[t] == h[t - start]) { m++; } } if (m == h.Length) { start += h.Length; } } Data = b.SubArray(start, finish - start); IsConversion = true; } } else { switch (b[8]) { case 0x00: var size = BitConverter.ToUInt32(b, 16); Data = new byte[size]; const int offset = 20; for (var i = offset; i < offset + size && i < b.Length; i++) { Data[i - offset] = b[i]; } IsValid = true; break; case 0x01: if (b[16] == 0x31) // Special case where b[16]==0x30 { for (var i = 18; i < b.Length; i++) { if (b[i - 1] == b[i] && b[i] == 0x00) { if (!settings.GetFlag("IgnoreInternalName")) { Name = Encoding.Unicode.GetString(b.SubArray(18, i - 18)); } i += 8; Data = b.SubArray(i, b.Length - i); IsValid = true; IsConversion = true; // This file will be saved as unnamed break; } } } break; } } } break; } }