#!/usr/bin/python

# A Python script to download and join large images served by Zoomify
# (http://www.zoomify.com)
#
# Requires PIL (http://www.pythonware.com/products/pil/)
#
# By GDR! (http://gdr.geekhood.net/)


from urllib import *
from pycurl import *
import StringIO
import Image

# The base URL of the Zoomify image - the page probably has something
# like /t.htm attached - just remove last this part.
base_url = 'http://www.kostrzyn.pl/plan_woodstock_2007/'

# The zoom level to retrieve. You'll probably be fine with the 
# default (5), but feel free to play around
level = 5

# Name of the output file, created in the current directory
outname = 'out.jpg'

# non-user-adjustable
xml = base_url + 'ImageProperties.xml'
group = 0
x = 0
y = 0
wid = 0
hei = 0

def img_url(g, x, y):
	"Turn coordinates into an URL"
	return '%sTileGroup%d/%d-%d-%d.jpg' % (base_url, g, level, x, y)
	
def get_img(gr, x, y):
	"Download an image with given coordinates, return 0 on 404"
	url = img_url(gr, x, y)
	buf = StringIO.StringIO()
	ch = Curl()
	ch.setopt(URL, url)
	ch.setopt(WRITEFUNCTION, buf.write)
	ch.perform()
	if(ch.getinfo(HTTP_CODE) != 404):
		f = open('%d-%d.jpg' % (x, y), 'wb')
		f.write(buf.getvalue())
		return 1
	else:
		return 0

# Yes, this is kind of brute force, but it's a hack and it's intended to work
def get_size():
	"Download images laying on the edges to test the width and height"
	print 'Measuring width...'
	x = 0
	gr = 0
	while 1:
		r = get_img(gr, x, 0)
		if r == 0:
			r = get_img(gr+1, x, 0)
			if r == 0:
#				x = x - 1
				break
			else:
				gr = gr + 1
		x = x+1
	print '%d tiles' % (x, )
	
	print 'Measuring height...'
	gr = 0
	y = 0
	while 1:
		r = get_img(gr, 0, y)
		if r == 0:
			r = get_img(gr+1, 0, y)
			if r == 0:
#				y = y - 1
				break
			else:
				gr = gr + 1
		y = y+1
	print '%d tiles' % (y, )
	return (x, y)
	
def get_components():
	"Get all tiles excluding row0/column0 that are already downloaded by get_width()"
	for x in range(1,wid):
		gr = 0
		for y in range(1,hei):
			r = get_img(gr, x, y)
			if r == 0:
				gr = gr + 1
				get_img(gr, x, y)
			print '(%d, %d) in gr %d' % (x, y, gr)
				
def compose(wid, hei):
	"Compose the images into one big image"
	print 'Composing images, out bitmap size: %d x %x' % (256*wid, 256*hei)
	im = Image.new('RGB', (256*wid, 256*hei))
	for x in range(0, wid):
		for y in range(0, hei):
			tile = Image.open('%d-%d.jpg' % (x, y))
			im.paste(tile, (256*x, 256*y))
	print 'Saving output image...'
	im.save(outname, 'JPEG')
	print 'Done'
			

# Run the process, if run as the main script	
if __name__ == "__main__":
	(wid, hei) = get_size()
	get_components()
	compose(wid, hei)
	
