Changed lines at line 22
22: We introduced a raster in which the images are scaled. This prevends the cache of get filled up with various fine grain scaled versions of the same image. The raster width is a configuration option which belongs to the caching group.
23: 1 Specification {anchor:Specification}
24: 1.1 Behaviour
25: 1.1.1 Request
26: A picture is requested with a picture path and a bounding box. The bounding box specifies the maximal size of the image. The Image Server has a configured raster in which it provides pictures. Lets assume the raster is set to 50 pixel. The picture size is scaled down to fit in the bounding box and then the width is rounded downwards to multiple of 50. (The height is obviously scaled down as well) The needed version of the picture is looked up in the cache and is generated if needed. The file name contains the dimensions and the request is answered using redirection to that file. That allows browser side caching even for slightly different bounding boxes.
27: 1.1.1 Raster
28: The raster value must be fixed over a reasonable time. The client shouldn't get different scaled images for the same requested dimension. In particular, the server is not allowed to serve a "good matching" version of an images which is a cache hit.
29: 1.1.1 Cache
30: The cache is an important part of the Image Server since it can reduce the server side load and the latency time. The cache has a space limit and the caching stategy is LRU (least recently used). The cached files should have the same modification date as the original file. Why? A file is deleted from the cache because of space limits. If it is requested again and the browser still has it in his cache it can be taken from there instead of downloaded again. Furthermore there should be a minimum lifetime of a chached file since the client needs to download them.
31: 1.1.1 Mirrors
32: A mirror should keep pictures in various sizes to save bandwidth or to gain faster access. It is also handy to be able to store the pictures on cheap webspace without CGI support. The Image Server has a mirror map where every mirror has a list of files it has. Furthermore there could be some information about the bandwith of the mirror. If a file is mirrored on more than one mirror is redirected to the one with more bandwidth. Loadbalancing is not reasonable since we loose the client-side caching.
33: 1.1 Interface
34: 1.1.1 CGI
35: The request URL is:
36: {code:none}
37: \http://<host>/<path>/imgserv.cgi?src=<image src>&width=<width>&height=<height>
38: {code}
39: Where __<image src>__ is an absolute path to the image form the document root.
40: Relative pathes are not possible since they are normally resolved by the browser. Therefor the Image Server cannot detemine the right path. __<width>__ and __<height>__ are integers greater than zero and denote the dimension of the requested image in pixel. Other units are not planed.
41: Examples:
42: {code:none}
43: \http://<host>/<path>/imgserv.cgi?src=images/1.jpg&width=800&height=600
44: \http://<host>/<path>/imgserv.cgi?src=gallery/holiday/1.jpg&width=1048&height=879
45: {code}
46: 1.1.1 Configuration
47: TODO: describe the configuration file syntax and options
48: 1 Implementation {anchor:Implementation}
49: 1.1 Language
50: [Haskell] is a great language for CGI scripts since it is pure functional has an easy to use CGI library.
51: 1.1 Raster
52: The dimension to serv is calculeted this way:
53: {code:java}
54: /*pseudo java code*/
55: int calcWidth; //bounding box fitting width
56: int calcHeight; //bounding box fitting height
57: int servWidth; //width to serve
58: int servHeight; //height to serve
59: int raster; //width of the raster
60: servWidth = (calcWidth / raster) * raster; //integer division
61: servHeight = (servWidth * calcHeight) / calcWidth;
62: {code}
63: This implementation maintains the side ratio of the image.
64: 1.1 Image scaleing and dimension retrieval
65: The {link:ImageMagick|http://www.imagemagick.org/} tool __identify__ is used to get the dimensions of an image and the __convert__ tool is used to scale them down.
66: 1.1.1 identify
67: {code:bash}
68: identify -format "%hx%w" source.image
69: > 640x480
70: {code}
71: 1.1.1 convert
72: {code:bash}
73: convert -sample height x width source.image resized.image
74: {code}
75: procudes an image that fits into the given bounding box. I.e. neither height nor width of the image is largen then the specified ones. convert respects the ratio of the image.
76: 1 Installation {anchor:Installation}
77: - install Hugs at the webserver machine
78: - check how to use cgi scripts with your webserver
79: - haskell cgi script are used like perl CGI scripts with the difference that runhugs is started instead of perl
80: - TODO: continue
81: We introduced a raster in which the images are scaled. This prevents the cache of get filled up with various fine grain scaled versions of the same image. The raster width is a configuration option which belongs to the caching group.
82: 1 Specification {anchor:Specification}
83: 1.1 Behaviour
84: 1.1.1 Request
85: A picture is requested with a picture path and a bounding box. The bounding box specifies the maximal size of the image. The Image Server has a configured raster in which it provides pictures. Lets assume the raster is set to 50 pixel. The picture size is scaled down to fit in the bounding box and then the width is rounded downwards to multiple of 50. (The height is obviously scaled down as well) The needed version of the picture is looked up in the cache and is generated if needed. The file name contains the dimensions and the request is answered using redirection to that file. That allows browser side caching even for slightly different bounding boxes.
86: 1.1.1 Raster
87: The raster value must be fixed over a reasonable time. The client shouldn't get different scaled images for the same requested dimension. In particular, the server is not allowed to serve a "good matching" version of an images which is a cache hit.
88: 1.1.1 Cache
89: The cache is an important part of the Image Server since it can reduce the server side load and the latency time. The cache has a space limit and the caching strategy is LRU (least recently used). The cached files should have the same modification date as the original file. Why? A file is deleted from the cache because of space limits. If it is requested again and the browser still has it in his cache it can be taken from there instead of downloaded again. Furthermore there should be a minimum lifetime of a cached file since the client needs to download them.
90: 1.1.1 Mirrors
91: A mirror should keep pictures in various sizes to save bandwidth or to gain faster access. It is also handy to be able to store the pictures on cheap web-space without CGI support. The Image Server has a mirror map where every mirror has a list of files it has. Furthermore there could be some information about the bandwidth of the mirror. If a file is mirrored on more than one mirror is redirected to the one with more bandwidth. Load balancing is not reasonable since we loose the client-side caching.
92: 1.1 Interface
93: 1.1.1 CGI
94: The request URL is:
95: {code:none}
96: \http://<host>/<path>/imgserv.cgi?src=<image src>&width=<width>&height=<height>
97: {code}
98: Where __<image src>__ is an absolute path to the image form the document root.
99: Relative paths are not possible since they are normally resolved by the browser. Therefor the Image Server cannot determine the right path. __<width>__ and __<height>__ are integers greater than zero and denote the dimension of the requested image in pixel. Other units are not planed.
100: Examples:
101: {code:none}
102: \http://<host>/<path>/imgserv.cgi?src=images/1.jpg&width=800&height=600
103: \http://<host>/<path>/imgserv.cgi?src=gallery/holiday/1.jpg&width=1048&height=879
104: {code}
105: 1.1.1 Configuration
106: TODO: describe the configuration file syntax and options
107: 1 Implementation {anchor:Implementation}
108: 1.1 Language
109: [Haskell] is a great language for CGI scripts since it is pure functional and has an easy to use CGI library. It is not that great with IO but you can code quite nice with it.
110: 1.1 Cache
111: The OS serves us with a filesystem. Let's use it!
112: The complete filesystem structure of the source image files is generated in the cache folder as well. For every file exists an info file with some information about the file, like dimension, file size, and all scaled versions with it's last use and sizes.
113: If an image is requested the info file is read. If it doesn't exist it is generated (inclusive directories if necessary). The containing file size is compared with the file size of the source image and if they differ all scaled version are deleted and the info file is rebuilt. Otherwise the requested dimension is looked up and if it exists it is delivered and the access time is written. If it doesn't exist it is generated (see next section).
114: After each creation the cache size is checked. In case it exceeds the given limit files are deleted which are least recently used. (access time) This is done until just 2/3 of the size limit is used. This makes sure the maintainance run isn't necessary too often.
115: 1.1 Image scaling and dimension retrieval
116: The {link:ImageMagick|http://www.imagemagick.org/} tool __identify__ is used to get the dimensions of an image and the __convert__ tool is used to scale them down.
117: 1.1.1 identify
118: {code:bash}
119: identify -format "%hx%w" source.image
120: > 640x480
121: {code}
122: 1.1.1 convert
123: {code:bash}
124: convert -sample height x width source.image resized.image
125: {code}
126: produces an image that fits into the given bounding box. I.e. neither height nor width of the image is larger than the specified ones. convert respects the ratio of the image.
127: 1.1 Raster
128: Since convert respects the ratio we only have to rasterise the bounding box's width.
129: {code:java}
130: rasteredWidth = (boundingBoxWidth div raster) * raster; // div = integer division
131: {code}
132: 1 Installation {anchor:Installation}
133: - Either compile a version for the OS on the web server machine or install hugs
134: - check how to use cgi scripts with your web server
135: - Haskell cgi script are used like perl CGI scripts with the difference that runhugs is started instead of perl or in case of a binary it is just executed