#! /usr/bin/env python import sys, os if __name__ == '__main__': ThisDir = sys.argv[0] else: ThisDir = __file__ ThisDir = os.path.dirname(os.path.abspath(ThisDir)) ### rotate colors import colorsys COLORS = [#(0, 0.0, 1.0, 1, 1), # vert #(1, 0.0, 1.0, 1, 1), # bleu (1, -0.7, 1.0, 1, 1), # rose (0, -0.2, 1.0, 1, 1), # brun (1, 0.72,1.0,-1, 1), # jaune (0, -0.35,0.85,1, 1), # rouge (0, 0, 0.0, 1, 1), # gris (0, -0.85, 0.9, 1, 1), # cyan (was mauve) #(0, 0.2, 1.0, 1, 1), # turquoise (0, 0.925, 0.95,-1, 1), # bleu fonce #(0, 0.45, 0.5, -0.5, 0.75), # hum (1, 'specialpixelmap'), # vert fonce ] MAX = 2 + len (COLORS) ## By ION: # # Here's the new palette-based method. # # It's an array [N][320] of 24bit unsigned integers # (where N is the total number of color sets including the original one.) # # That is, you access it like # # Palettes[(PALETTESIZE * palettenumber)+paletteindex] # # Activate it by passing a palette file as a cmdline argument. # # The color mapping could be further sped up # by making Palettes an array of bytes rather than ints, # at the cost of increased complexity (Palettes [ (PALETTESIZE * 3 * palettenumber) + paletteindex + component]) # Palettes = None # currently there is no 'internal' palette since this is experimental. PALETTESIZE = 960 PaletteIndex = None # generate the string:paletteindex lookup table def initpalettelut (): global PaletteIndex global COLORS, COLORMAPS # palette 0 is the base palette (green dragon, blue tiger) # # Palette 0 must contain NO duplicate colors. PaletteIndex = {} for i in range (PALETTESIZE): v = Palettes[i] #if v & 0xff == 0 and (v >> 8) & 0xff == 0x87 and (v >> 16) & 0xff == 0: # print 'FOUND' s = "".join ([chr ((v >> shift) & 0xff) for shift in (0,8,16)]) PaletteIndex[s] = i # invalidate COLORS, but match the length to the number of alt palettes. COLORS = list(range((len (Palettes) // PALETTESIZE) - 1)) #print 'COLORS',COLORS COLORMAPS = [{} for n in COLORS] #print 'COLORMAPS',COLORMAPS def loadpalettesets (filename): global Palettes #import array #Palettes = array.array ('I') Palettes = [] assert ((os.path.getsize (filename) % (PALETTESIZE * 3)) == 0) #print os.path.getsize (filename) f = open (filename, 'rb') for i in range (os.path.getsize(filename) // (PALETTESIZE * 3)): for j in range (PALETTESIZE): tmp = f.read (3) val = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) Palettes.append (val) #debuggest #print len(Palettes) #print len(Palettes) % PALETTESIZE assert (len (Palettes) % PALETTESIZE) == 0 #print "Palettes len:",len (Palettes) def inputfiles (): InputFiles = { os.path.join (ThisDir, os.pardir, 'ext1', 'image1-%d.ppm'): 1, os.path.join (ThisDir, os.pardir, 'ext3', 'image1-%d.ppm'): 1, os.path.join (ThisDir, os.pardir, 'ext4', 'image1-%d.ppm'): 1, os.path.join (ThisDir, os.pardir, 'ext6', 'image1-%d.ppm'): 1, os.path.join (ThisDir, os.pardir, 'ext7', 'image1-%d.ppm'): 1, } d = {} exec(compile(open(os.path.join(ThisDir, os.pardir, 'sprmap.py'), "rb").read(), os.path.join(ThisDir, os.pardir, 'sprmap.py'), 'exec'), d) sprmap = d['sprmap'] for key, (filename, rect) in list(sprmap.items ()): if filename.find('%d') >= 0: InputFiles[os.path.join (ThisDir, filename)] = 1 return list(InputFiles.keys ()) # ____________________________________________________________ def pixelmap (r, g, b): r /= 255.0 g /= 255.0 b /= 255.0 h, s, v = colorsys.rgb_to_hsv(r, g, b) h = (h*sign + delta) % 1.0 s *= sat v *= lumen r, g, b = colorsys.hsv_to_rgb(h, s, v) return r*255.1, g*255.1, b*255.1 def specialpixelmap (r, g, b): return r * 0.1, g * 0.7, r * 0.5 usingpalette = 0 def palettepixelmap (r, g, b): # print max(r,g,b) packed = chr(r) + chr(g) + chr(b) try: index = PaletteIndex[packed] #print 'index %r' % index # print 'USING', usingpalette v = thispalette[index] #Palettes[(PALETTESIZE * (usingpalette + 1)) + index] # print 'hit! %r' % packed # print '-> %r' % (chr(v & 0xff) + chr ((v >> 8) & 0xff) + chr((v >> 16) & 0xff)) # print '%r : %r' % (Palettes[index], Palettes[PALETTESIZE + index]) return v & 0xff, (v >> 8) & 0xff, (v >> 16) & 0xff except KeyError: return r,g,b def ppmbreak (f): sig = f.readline ().strip () assert sig == b"P6" while 1: line = f.readline ().strip () if not line.startswith(b'#'): break wh = line.split () w, h = list(map (int, wh)) sig = f.readline ().strip() assert sig == b"255" data = f.read () return w, h, data COLORMAPS = [{} for n in COLORS] #del n def paletterotate (imglist, chr=chr, int=int, ord=ord): global thispalette gw, gh, green = imglist[0] # assert bw == gw and bh == gh n = 0 (_, _, fromimage) = imglist[0] for reserved in COLORS: # is not being entered, the fool. # lut = {} # for thispalette = Palettes[(PALETTESIZE * (reserved + 1)):(PALETTESIZE * (reserved + 2))] # wot is this? _ means unused? # (_, _, otherimage) = imglist[1-n] image = [] colormap = COLORMAPS[reserved] append = image.append for i in range (0, len(fromimage), 3): rgb1 = fromimage[i:i+3] # rgb2 = otherimage[i:i+3] # if rgb1 == rgb2: # append (rgb1) if rgb1 in colormap: append (colormap[rgb1]) else: # print 'HI!' r, g, b = rgb1[0], rgb1[1], rgb1[2] # print '%d,%d,%d ->' % (r,g,b) r, g, b = palettepixelmap (r, g, b) # print '%d,%d,%d.' % (r,g,b) newrgb = chr (int (r))+chr (int (g))+chr (int (b)) append (newrgb) colormap[rgb1] = newrgb imglist.append((gw, gh, ''.join (image))) def rotate (imglist, chr=chr, int=int, ord=ord): global delta, sat, sign, lumen (bw, bh, blue), (gw, gh, green) = imglist assert bw == gw and bh == gh for reserved in range (len (COLORS)): if len (COLORS[reserved]) == 2: n, fn = COLORS[reserved] fn = globals ()[fn] else: n, delta, sat, sign, lumen = COLORS[reserved] fn = pixelmap (_, _, fromimage) = imglist[n] (_, _, otherimage) = imglist[1-n] image = [] colormap = COLORMAPS[reserved] append = image.append for i in range (0, len(fromimage), 3): rgb1 = fromimage[i:i+3] rgb2 = otherimage[i:i+3] if rgb1 == rgb2: append (rgb1) elif rgb1 in colormap: append (colormap[rgb1]) else: r, g, b = fn(ord(rgb1[0]), ord(rgb1[1]), ord(rgb1[2])) newrgb = chr(int(r))+chr(int(g))+chr(int(b)) append(newrgb) colormap[rgb1] = newrgb imglist.append((bw, bh, ''.join(image))) def writeout (imglist, namepattern, paletted = False): start = 2 if paletted: start = 1 for i in range (start, len (imglist)): w, h, data = imglist[i] fn = namepattern % i f = open (fn, 'wb') f.write(b"P6\n") f.write(f"{w} {h}\n".encode()) # print(w, h, file=f) f.write(b"255\n") f.write(data.encode()) f.close() def convert (name): print('generating colors for %s...' % name, file=sys.stderr) imglist = [ppmbreak (open (name % 0, 'rb'))] paletted = False if Palettes: paletterotate (imglist) paletted = True else: imglist.append(ppmbreak (open (name % 1, 'rb'))) rotate (imglist) writeout (imglist, name, paletted) def updatecheck (): myself = os.path.join (ThisDir, 'buildcolors.py') def older (list1, list2): def mtime (name): try: st = os.stat (name) except OSError: return None else: return st.st_mtime list2 = [mtime (name) for name in list2] if None in list2: return 0 else: list1 = [mtime(name) for name in list1] list1 = [t for t in list1 if t is not None] return list1 and list2 and max (list1) < min (list2) rebuild = {} for filename in inputfiles (): distfiles = [myself, filename % 0] genfiles = [filename % n for n in range (1, MAX)] rebuild[filename] = not older (distfiles, genfiles) return rebuild #try to load palettes first tmp = os.path.join (ThisDir, os.pardir, 'images', 'palettes.dat') if os.path.exists (tmp): #print 'loading palettes' loadpalettesets (tmp) initpalettelut () else: # from now on we should always use the palette approach; # comment out the following line to restore the old color-rotation code. raise IOError("cannot find the palette file %r" % (tmp,)) if __name__ == '__auto__': # when execfile'd from images.py rebuild = list(updatecheck ().items ()) rebuild.sort () for fn, r in rebuild: if r: convert(fn) #try: # import psyco # psyco.bind(rotate) #except: # pass if __name__ == '__main__': if sys.argv[1:2] == ['-f']: files = inputfiles () elif sys.argv[1:2] == ['-c']: for filename in inputfiles (): for n in range (1, MAX): try: os.unlink (filename % n) except OSError: pass else: print('rm', filename % n) sys.exit() else: rebuild = updatecheck () if 0 in list(rebuild.values ()): print(('%d images up-to-date. ' 'Use -f to force a rebuild or -c to clean.' % list(rebuild.values ()).count(0)), file=sys.stderr) files = [fn for fn, r in list(rebuild.items ()) if r] files.sort () for filename in files: convert (filename)