import java.awt.Graphics2D;\r
import java.awt.image.BufferedImage;\r
import java.awt.image.WritableRaster;\r
+import java.io.BufferedReader;\r
import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileReader;\r
import java.io.FileWriter;\r
import java.io.FilenameFilter;\r
import java.io.IOException;\r
+import java.math.BigInteger;\r
+import java.security.MessageDigest;\r
+import java.security.NoSuchAlgorithmException;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
import java.util.Collections;\r
import java.util.Comparator;\r
import java.util.HashMap;\r
+import java.util.Map.Entry;\r
import java.util.regex.Matcher;\r
import java.util.regex.Pattern;\r
+import java.util.zip.CRC32;\r
\r
import javax.imageio.ImageIO;\r
\r
public int minHeight = 16;\r
public int maxWidth = 1024;\r
public int maxHeight = 1024;\r
+ public boolean incremental;\r
+\r
+ HashMap<String, Long> crcs = new HashMap();\r
}\r
\r
static private void process (Settings settings, File inputDir, File outputDir, File packFile) throws IOException {\r
if (file.getName().startsWith(prefix)) file.delete();\r
}\r
\r
+ // Abort if nothing has changed.\r
+ if (settings.incremental) {\r
+ File[] files = inputDir.listFiles();\r
+ if (files == null) return;\r
+ boolean noneHaveChanged = true;\r
+ int childCountNow = 0;\r
+ for (File file : files) {\r
+ if (file.isDirectory()) continue;\r
+ String path = file.getAbsolutePath();\r
+ Long crcOld = settings.crcs.get(path);\r
+ long crcNow = crc(file);\r
+ if (crcOld == null || crcOld != crcNow) noneHaveChanged = false;\r
+ settings.crcs.put(path, crcNow);\r
+ childCountNow++;\r
+ }\r
+ String path = inputDir.getAbsolutePath();\r
+ Long childCountOld = settings.crcs.get(path);\r
+ if (childCountOld == null || childCountNow != childCountOld) noneHaveChanged = false;\r
+ settings.crcs.put(path, (long)childCountNow);\r
+ if (noneHaveChanged) {\r
+ System.out.println(inputDir);\r
+ System.out.println("Skipping unchanged directory.");\r
+ System.out.println();\r
+ return;\r
+ }\r
+ }\r
+\r
// Just check all combinations, because we are extremely lazy.\r
ArrayList<TextureFilter> filters = new ArrayList();\r
filters.add(null);\r
File packFile = new File(outputDir, "pack");\r
packFile.delete();\r
\r
+ // Load incremental data.\r
+ File incrmentalFile = null;\r
+ if (settings.incremental) {\r
+ settings.crcs.clear();\r
+ incrmentalFile = new File(System.getProperty("user.home") + "/.texturepacker/" + hash(inputDir.getAbsolutePath()));\r
+ if (incrmentalFile.exists()) {\r
+ BufferedReader reader = new BufferedReader(new FileReader(incrmentalFile));\r
+ while (true) {\r
+ String path = reader.readLine();\r
+ if (path == null) break;\r
+ String crc = reader.readLine();\r
+ if (crc == null) break;\r
+ settings.crcs.put(path, Long.parseLong(crc));\r
+ }\r
+ reader.close();\r
+ }\r
+ }\r
+\r
process(settings, inputDir, outputDir, packFile);\r
+\r
+ if (settings.incremental) {\r
+ incrmentalFile.getParentFile().mkdirs();\r
+ FileWriter writer = new FileWriter(incrmentalFile);\r
+ for (Entry<String, Long> entry : settings.crcs.entrySet()) {\r
+ writer.write(entry.getKey() + "\n");\r
+ writer.write(entry.getValue() + "\n");\r
+ }\r
+ writer.close();\r
+ }\r
+ }\r
+\r
+ static private String hash (String value) {\r
+ try {\r
+ MessageDigest digest = MessageDigest.getInstance("SHA1");\r
+ digest.update(value.getBytes());\r
+ return new BigInteger(1, digest.digest()).toString(16);\r
+ } catch (NoSuchAlgorithmException ex) {\r
+ throw new RuntimeException(ex);\r
+ }\r
+ }\r
+\r
+ static private long crc (File file) {\r
+ try {\r
+ FileInputStream input = new FileInputStream(file);\r
+ byte[] buffer = new byte[4096];\r
+ CRC32 crc32 = new CRC32();\r
+ while (true) {\r
+ int length = input.read(buffer);\r
+ if (length == -1) break;\r
+ crc32.update(buffer, 0, length);\r
+ }\r
+ input.close();\r
+ return crc32.getValue();\r
+ } catch (IOException ex) {\r
+ throw new RuntimeException(ex);\r
+ }\r
}\r
\r
static public void main (String[] args) throws Exception {\r