1: <?php
2: 3: 4: 5: 6:
7:
8:
9:
10: 11: 12: 13: 14: 15: 16:
17: function imageError($status_text, $errormessage, $errorimg = 'err-imagegeneral.png') {
18: global $newfilename, $album, $image;
19: $debug = isset($_GET['debug']);
20: if ($debug) {
21: echo('<strong>' . sprintf(gettext('Zenphoto Image Processing Error: %s'), $errormessage) . '</strong>'
22: . '<br /><br />' . sprintf(gettext('Request URI: [ <code>%s</code> ]'), html_encode(getRequestURI()))
23: . '<br />PHP_SELF: [ <code>' . html_encode($_SERVER['PHP_SELF']) . '</code> ]'
24: . (empty($newfilename) ? '' : '<br />' . sprintf(gettext('Cache: [<code>%s</code>]'), '/' . CACHEFOLDER . '/' . html_encode(sanitize($newfilename, 3))) . ' ')
25: . (empty($image) || empty($album) ? '' : ' <br />' . sprintf(gettext('Image: [<code>%s</code>]'), html_encode(sanitize($album . '/' . $image, 3))) . ' <br />'));
26: } else {
27: if (DEBUG_IMAGE_ERR) {
28: trigger_error($errormessage, E_USER_NOTICE);
29: }
30: header("HTTP/1.0 $status_text");
31: header("Status: $status_text");
32: header('Location: ' . FULLWEBPATH . '/' . ZENFOLDER . '/images/' . $errorimg);
33: }
34: exitZP();
35: }
36:
37: 38: 39: 40: 41: 42: 43: 44:
45: function imageDebug($album, $image, $args, $imgfile) {
46: list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop) = $args;
47: echo "Album: [ " . $album . " ], Image: [ " . $image . " ]<br /><br />";
48: if (file_exists($imgfile)) {
49: echo "Image filesize: " . filesize($imgfile);
50: } else {
51: echo "Image file not found.";
52: }
53: echo '<br /><br />';
54: echo "<strong>" . gettext("Debug") . " <code>i.php</code> | " . gettext("Arguments:") . "</strong><br />\n\n"
55: ?>
56: <ul>
57: <li><?php echo gettext("size ="); ?> <strong> <?php echo sanitize($size, 3) ?> </strong></li>
58: <li><?php echo gettext("width =") ?> <strong> <?php echo sanitize($width, 3) ?> </strong></li>
59: <li><?php echo gettext("height =") ?> <strong> <?php echo sanitize($height, 3) ?> </strong></li>
60: <li><?php echo gettext("cw =") ?> <strong> <?php echo sanitize($cw, 3) ?> </strong></li>
61: <li><?php echo gettext("ch =") ?> <strong> <?php echo sanitize($ch, 3) ?> </strong></li>
62: <li><?php echo gettext("cx =") ?> <strong> <?php echo sanitize($cx, 3) ?> </strong></li>
63: <li><?php echo gettext("cy =") ?> <strong> <?php echo sanitize($cy, 3) ?> </strong></li>
64: <li><?php echo gettext("quality =") ?> <strong> <?php echo sanitize($quality, 3) ?> </strong></li>
65: <li><?php echo gettext("thumb =") ?> <strong> <?php echo sanitize($thumb, 3) ?> </strong></li>
66: <li><?php echo gettext("crop =") ?> <strong> <?php echo sanitize($crop, 3) ?> </strong></li>
67: </ul>
68: <?php
69: }
70:
71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86:
87: function propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim) {
88: $hprop = round(($h / $w) * $dim);
89: $wprop = round(($w / $h) * $dim);
90: if ($size) {
91: if ((($thumb || ($image_use_side == 'longest')) && $h > $w) || ($image_use_side == 'height') || ($image_use_side == 'shortest' && $h < $w)) {
92: $newh = $dim;
93: $neww = $wprop;
94: } else {
95: $neww = $dim;
96: $newh = $hprop;
97: }
98: } else {
99: if ($height) {
100: $newh = $height;
101: } else {
102: $newh = $hprop;
103: }
104: if ($width) {
105: $neww = $width;
106: } else {
107: $neww = $wprop;
108: }
109: }
110: if (DEBUG_IMAGE)
111: debugLog("propSizes(\$size=$size, \$width=$width, \$height=$height, \$w=$w, \$h=$h, \$thumb=$thumb, \$image_use_side=$image_use_side, \$dim=$dim):: \$wprop=$wprop; \$hprop=$hprop; \$neww=$neww; \$newh=$newh");
112: return array($neww, $newh);
113: }
114:
115: 116: 117: 118: 119: 120:
121: function iptc_make_tag($rec, $data, $value) {
122: $length = strlen($value);
123: $retval = chr(0x1C) . chr($rec) . chr($data);
124: if ($length < 0x8000) {
125: $retval .= chr($length >> 8) . chr($length & 0xFF);
126: } else {
127: $retval .= chr(0x80) . chr(0x04) . chr(($length >> 24) & 0xFF) . chr(($length >> 16) & 0xFF) . chr(($length >> 8) & 0xFF) . chr($length & 0xFF);
128: }
129: return $retval . $value;
130: }
131:
132: 133: 134: 135: 136: 137: 138: 139: 140: 141:
142: function cacheImage($newfilename, $imgfile, $args, $allow_watermark = false, $theme, $album) {
143: global $_zp_gallery;
144: try {
145: @list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop, $thumbstandin, $passedWM, $adminrequest, $effects) = $args;
146:
147: $image_use_side = getOption('image_use_side');
148: $upscale = getOption('image_allow_upscale');
149: $allowscale = true;
150: $sharpenthumbs = getOption('thumb_sharpen');
151: $sharpenimages = getOption('image_sharpen');
152: $id = $im = NULL;
153: $watermark_use_image = getAlbumInherited($album, 'watermark', $id);
154: if (empty($watermark_use_image)) {
155: $watermark_use_image = IMAGE_WATERMARK;
156: }
157: if (!$effects) {
158: if ($thumb && getOption('thumb_gray')) {
159: $effects = 'gray';
160: } else if (getOption('image_gray')) {
161: $effects = 'gray';
162: }
163: }
164: $newfile = SERVERCACHE . $newfilename;
165: mkdir_recursive(dirname($newfile), FOLDER_MOD);
166: if (DEBUG_IMAGE)
167: debugLog("cacheImage(\$imgfile=" . basename($imgfile) . ", \$newfilename=$newfilename, \$allow_watermark=$allow_watermark, \$theme=$theme) \$size=$size, \$width=$width, \$height=$height, \$cw=$cw, \$ch=$ch, \$cx=" . (is_null($cx) ? 'NULL' : $cx) . ", \$cy=" . (is_null($cy) ? 'NULL' : $cy) . ", \$quality=$quality, \$thumb=$thumb, \$crop=$crop \$image_use_side=$image_use_side; \$upscale=$upscale);");
168:
169: if (!file_exists($imgfile) || !is_readable($imgfile)) {
170: imageError('404 Not Found', sprintf(gettext('Image %s not found or is unreadable.'), filesystemToInternal($imgfile)), 'err-imagenotfound.png');
171: }
172: $rotate = false;
173: if (zp_imageCanRotate()) {
174: $rotate = getImageRotation($imgfile);
175: }
176: $s = getSuffix($imgfile);
177: if (function_exists('exif_thumbnail') && getOption('use_embedded_thumb') && ($s == 'jpg' || $s == 'jpeg')) {
178: $im = exif_thumbnail($imgfile, $tw, $th, $tt);
179: if ($im) {
180: if ($size) {
181: $big_enough = $tw >= $size && $th >= $size;
182: } else {
183: $big_enough = $tw >= $width && $th >= $height;
184: }
185: if ($big_enough) {
186: $im = zp_imageFromString($im);
187: if (DEBUG_IMAGE && $im)
188: debugLog(sprintf(gettext('Using %1$ux%2$u %3$s thumbnail image.'), $tw, $th, image_type_to_mime_type($tt)));
189: } else {
190: $im = false;
191: }
192: } else {
193: $im = false;
194: }
195: }
196: if (!$im) {
197: $im = zp_imageGet($imgfile);
198: }
199: if (!$im) {
200: imageError('404 Not Found', sprintf(gettext('Image %s not renderable (imageGet).'), filesystemToInternal($imgfile)), 'err-failimage.png');
201: }
202: if ($rotate) {
203: if (DEBUG_IMAGE)
204: debugLog("cacheImage:rotate->$rotate");
205: $im = zp_rotateImage($im, $rotate);
206: if (!$im) {
207: imageError('404 Not Found', sprintf(gettext('Image %s not rotatable.'), filesystemToInternal($imgfile)), 'err-failimage.png');
208: }
209: }
210: $w = zp_imageWidth($im);
211: $h = zp_imageHeight($im);
212:
213: $ratio_in = '';
214: $ratio_out = '';
215: $crop = ($crop || $cw != 0 || $ch != 0);
216: if (!empty($size)) {
217: $dim = $size;
218: if ($crop) {
219: $dim = $size;
220: if (!$ch)
221: $ch = $size;
222: if (!$cw)
223: $cw = $size;
224: $width = $cw;
225: $height = $ch;
226: $size = false;
227: } else {
228: $width = $height = false;
229: }
230: } else if (!empty($width) && !empty($height)) {
231: $ratio_in = $h / $w;
232: $ratio_out = $height / $width;
233: if ($ratio_in > $ratio_out) {
234: $thumb = true;
235: $dim = $width;
236: if (!$ch)
237: $ch = $height;
238: } else {
239: $dim = $height;
240: if (!$cw)
241: $cw = $width;
242: }
243: } else if (!empty($width)) {
244: $dim = $width;
245: $size = $height = false;
246: } else if (!empty($height)) {
247: $dim = $height;
248: $size = $width = false;
249: } else {
250:
251: imageError('404 Not Found', sprintf(gettext('Unknown error processing %s! Please report to the developers at <a href="http://www.zenphoto.org/">www.zenphoto.org</a>'), filesystemToInternal($imgfile)), 'err-imagegeneral.png');
252: }
253:
254: $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim);
255: list($neww, $newh) = $sizes;
256:
257: if (DEBUG_IMAGE)
258: debugLog("cacheImage:" . basename($imgfile) . ": \$size=$size, \$width=$width, \$height=$height, \$w=$w; \$h=$h; \$cw=$cw, " .
259: "\$ch=$ch, \$cx=$cx, \$cy=$cy, \$quality=$quality, \$thumb=$thumb, \$crop=$crop, \$newh=$newh, \$neww=$neww, \$dim=$dim, " .
260: "\$ratio_in=$ratio_in, \$ratio_out=$ratio_out \$upscale=$upscale \$rotate=$rotate \$effects=$effects");
261:
262: if (!$upscale && $newh >= $h && $neww >= $w) {
263: $neww = $w;
264: $newh = $h;
265: $allowscale = false;
266: if ($crop) {
267: if ($width > $neww) {
268: $width = $neww;
269: }
270: if ($height > $newh) {
271: $height = $newh;
272: }
273: }
274: if (DEBUG_IMAGE)
275: debugLog("cacheImage:no upscale " . basename($imgfile) . ": \$newh=$newh, \$neww=$neww, \$crop=$crop, \$thumb=$thumb, \$rotate=$rotate, watermark=" . $watermark_use_image);
276: }
277:
278: $watermark_image = false;
279: if ($passedWM) {
280: if ($passedWM != NO_WATERMARK) {
281: $watermark_image = getWatermarkPath($passedWM);
282: if (!file_exists($watermark_image)) {
283: $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
284: }
285: }
286: } else {
287: if ($allow_watermark) {
288: $watermark_image = $watermark_use_image;
289: if ($watermark_image) {
290: if ($watermark_image != NO_WATERMARK) {
291: $watermark_image = getWatermarkPath($watermark_image);
292: if (!file_exists($watermark_image)) {
293: $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
294: }
295: }
296: }
297: }
298: }
299:
300:
301: if ($crop) {
302: if ($cw > $ch) {
303: $ir = $ch / $cw;
304: } else {
305: $ir = $cw / $ch;
306: }
307: if ($size) {
308: $neww = $size;
309: $newh = $ir * $size;
310: } else {
311: $neww = $width;
312: $newh = $height;
313: if ($neww > $newh) {
314: if ($newh === false) {
315: $newh = $ir * $neww;
316: }
317: } else {
318: if ($neww === false) {
319: $neww = $ir * $newh;
320: }
321: }
322: }
323: if (is_null($cx) && is_null($cy)) {
324:
325: $cf = 1;
326: if ($cw)
327: $cf = min($cf, $cw / $neww);
328: if ($ch)
329: $cf = min($cf, $ch / $newh);
330:
331: if (!$cw || $w / $cw * $ch > $h) {
332: $cw = round($h / $ch * $cw * $cf);
333: $ch = round($h * $cf);
334: $cx = round(($w - $cw) / 3);
335: } else {
336: $ch = round($w / $cw * $ch * $cf);
337: $cw = round($w * $cf);
338: $cy = round(($h - $ch) / 3);
339: }
340: } else {
341: if (!$cw || $cw > $w)
342: $cw = $w;
343: if (!$ch || $ch > $h)
344: $ch = $h;
345: }
346:
347: if ($cw + $cx > $w)
348: $cx = $w - $cw;
349: if ($cx < 0) {
350: $cw = $cw + $cx;
351: $cx = 0;
352: }
353: if ($ch + $cy > $h)
354: $cy = $h - $ch;
355: if ($cy < 0) {
356: $ch = $ch + $cy;
357: $cy = 0;
358: }
359: if (DEBUG_IMAGE)
360: debugLog("cacheImage:crop " . basename($imgfile) . ":\$size=$size, \$width=$width, \$height=$height, \$cw=$cw, \$ch=$ch, \$cx=$cx, \$cy=$cy, \$quality=$quality, \$thumb=$thumb, \$crop=$crop, \$rotate=$rotate");
361: $newim = zp_createImage($neww, $newh);
362: if (!zp_resampleImage($newim, $im, 0, 0, $cx, $cy, $neww, $newh, $cw, $ch)) {
363: imageError('404 Not Found', sprintf(gettext('Image %s not renderable (resample).'), filesystemToInternal($imgfile)), 'err-failimage.png');
364: }
365: } else {
366: if ($newh >= $h && $neww >= $w && !$rotate && !$effects && !$watermark_image && (!$upscale || $newh == $h && $neww == $w)) {
367:
368: if (SYMLINK && @symlink($imgfile, $newfile)) {
369: if (DEBUG_IMAGE)
370: debugLog("cacheImage:symlink original " . basename($imgfile) . ":\$size=$size, \$width=$width, \$height=$height, \$dim=$dim, \$neww=$neww; \$newh=$newh; \$quality=$quality, \$thumb=$thumb, \$crop=$crop, \$rotate=$rotate; \$allowscale=$allowscale;");
371: clearstatcache();
372: return true;
373: } else if (@copy($imgfile, $newfile)) {
374: if (DEBUG_IMAGE)
375: debugLog("cacheImage:copy original " . basename($imgfile) . ":\$size=$size, \$width=$width, \$height=$height, \$dim=$dim, \$neww=$neww; \$newh=$newh; \$quality=$quality, \$thumb=$thumb, \$crop=$crop, \$rotate=$rotate; \$allowscale=$allowscale;");
376: clearstatcache();
377: return true;
378: }
379: }
380: if ($allowscale) {
381: $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim);
382: list($neww, $newh) = $sizes;
383: }
384: if (DEBUG_IMAGE)
385: debugLog("cacheImage:no crop " . basename($imgfile) . ":\$size=$size, \$width=$width, \$height=$height, \$dim=$dim, \$neww=$neww; \$newh=$newh; \$quality=$quality, \$thumb=$thumb, \$crop=$crop, \$rotate=$rotate; \$allowscale=$allowscale;");
386: $newim = zp_createImage($neww, $newh);
387: if (!zp_resampleImage($newim, $im, 0, 0, 0, 0, $neww, $newh, $w, $h)) {
388: imageError('404 Not Found', sprintf(gettext('Image %s not renderable (resample).'), filesystemToInternal($imgfile)), 'err-failimage.png');
389: }
390: if (($thumb && $sharpenthumbs) || (!$thumb && $sharpenimages)) {
391: if (!zp_imageUnsharpMask($newim, getOption('sharpen_amount'), getOption('sharpen_radius'), getOption('sharpen_threshold'))) {
392: imageError('404 Not Found', sprintf(gettext('Image %s not renderable (unsharp).'), filesystemToInternal($imgfile)), 'err-failimage.png');
393: }
394: }
395: }
396:
397: $imgEffects = explode(',', $effects);
398: if (in_array('gray', $imgEffects)) {
399: zp_imageGray($newim);
400: }
401:
402: if ($watermark_image) {
403: $offset_h = getOption('watermark_h_offset') / 100;
404: $offset_w = getOption('watermark_w_offset') / 100;
405: $percent = getOption('watermark_scale') / 100;
406: $watermark = zp_imageGet($watermark_image);
407: if (!$watermark) {
408: imageError('404 Not Found', sprintf(gettext('Watermark %s not renderable.'), $watermark_image), 'err-failimage.png');
409: }
410: $watermark_width = zp_imageWidth($watermark);
411: $watermark_height = zp_imageHeight($watermark);
412: $imw = zp_imageWidth($newim);
413: $imh = zp_imageHeight($newim);
414: $nw = sqrt(($imw * $imh * $percent) * ($watermark_width / $watermark_height));
415: $nh = $nw * ($watermark_height / $watermark_width);
416: $r = sqrt(($imw * $imh * $percent) / ($watermark_width * $watermark_height));
417: if (!getOption('watermark_allow_upscale')) {
418: $r = min(1, $r);
419: }
420: $nw = round($watermark_width * $r);
421: $nh = round($watermark_height * $r);
422: if (($nw != $watermark_width) || ($nh != $watermark_height)) {
423: $watermark = zp_imageResizeAlpha($watermark, $nw, $nh);
424: if (!$watermark) {
425: imageError('404 Not Found', sprintf(gettext('Watermark %s not resizeable.'), $watermark_image), 'err-failimage.png');
426: }
427: }
428:
429: $dest_x = max(0, floor(($imw - $nw) * $offset_w));
430: $dest_y = max(0, floor(($imh - $nh) * $offset_h));
431: if (DEBUG_IMAGE)
432: debugLog("Watermark:" . basename($imgfile) . ": \$offset_h=$offset_h, \$offset_w=$offset_w, \$watermark_height=$watermark_height, \$watermark_width=$watermark_width, \$imw=$imw, \$imh=$imh, \$percent=$percent, \$r=$r, \$nw=$nw, \$nh=$nh, \$dest_x=$dest_x, \$dest_y=$dest_y");
433: if (!zp_copyCanvas($newim, $watermark, $dest_x, $dest_y, 0, 0, $nw, $nh)) {
434: imageError('404 Not Found', sprintf(gettext('Image %s not renderable (copycanvas).'), filesystemToInternal($imgfile)), 'err-failimage.png');
435: }
436: zp_imageKill($watermark);
437: }
438:
439:
440: @chmod($newfile, 0777);
441: if (zp_imageOutput($newim, getSuffix($newfile), $newfile, $quality)) {
442: if (getOption('ImbedIPTC') && getSuffix($newfilename) == 'jpg' && GRAPHICS_LIBRARY != 'Imagick') {
443: global $_zp_extra_filetypes;
444: if (!$_zp_extra_filetypes)
445: $_zp_extra_filetypes = array();
446: require_once(dirname(__FILE__) . '/functions.php');
447: $iptc = array(
448: '1#090' => chr(0x1b) . chr(0x25) . chr(0x47),
449: '2#115' => $_zp_gallery->getTitle()
450: );
451: $iptc_data = zp_imageIPTC($imgfile);
452: if ($iptc_data) {
453: $iptc_data = iptcparse($iptc_data);
454: if ($iptc_data)
455: $iptc = array_merge($iptc_data, $iptc);
456: }
457: $imgfile = str_replace(ALBUM_FOLDER_SERVERPATH, '', $imgfile);
458: $imagename = basename($imgfile);
459: $albumname = dirname($imgfile);
460: $image = newImage(newAlbum($albumname), $imagename);
461: $copyright = $image->getCopyright();
462: if (empty($copyright)) {
463: $copyright = getOption('default_copyright');
464: }
465: if (!empty($copyright)) {
466: $iptc['2#116'] = $copyright;
467: }
468: $credit = $image->getCredit();
469: if (!empty($credit)) {
470: $iptc['2#110'] = $credit;
471: }
472: $iptc_result = '';
473: foreach ($iptc as $tag => $string) {
474: $tag_parts = explode('#', $tag);
475: if (is_array($string)) {
476: foreach ($string as $element) {
477: $iptc_result .= iptc_make_tag($tag_parts[0], $tag_parts[1], $element);
478: }
479: } else {
480: $iptc_result .= iptc_make_tag($tag_parts[0], $tag_parts[1], $string);
481: }
482: }
483: $content = iptcembed($iptc_result, $newfile);
484: $fw = fopen($newfile, 'w');
485: fwrite($fw, $content);
486: fclose($fw);
487: clearstatcache();
488: }
489: @chmod($newfile, FILE_MOD);
490: if (DEBUG_IMAGE)
491: debugLog('Finished:' . basename($imgfile));
492: } else {
493: if (DEBUG_IMAGE)
494: debugLog('cacheImage: failed to create ' . $newfile);
495: imageError('404 Not Found', sprintf(gettext('cacheImage: failed to create %s'), $newfile), 'err-failimage.png');
496: }
497: @chmod($newfile, FILE_MOD);
498: zp_imageKill($newim);
499: zp_imageKill($im);
500: } catch (Exception $e) {
501: debugLog('cacheImage(' . $newfilename . ') exception: ' . $e->getMessage());
502: imageError('404 Not Found', sprintf(gettext('cacheImage(%1$s) exception: %2$s'), $newfilename, $e->getMessage()), 'err-failimage.png');
503: return false;
504: }
505: clearstatcache();
506: return true;
507: }
508:
509: 510: 511: 512: 513: 514: 515: 516: 517: 518:
519:
520: function getImageRotation($imgfile) {
521: $imgfile = substr(filesystemToInternal($imgfile), strlen(ALBUM_FOLDER_SERVERPATH));
522: $result = query_single_row('SELECT EXIFOrientation FROM ' . prefix('images') . ' AS i JOIN ' . prefix('albums') . ' as a ON i.albumid = a.id WHERE ' . db_quote($imgfile) . ' = CONCAT(a.folder,"/",i.filename)');
523: if (is_array($result) && array_key_exists('EXIFOrientation', $result)) {
524: $splits = preg_split('/!([(0-9)])/', $result['EXIFOrientation']);
525: $rotation = $splits[0];
526: switch ($rotation) {
527: case 1 : return false;
528: case 2 : return false;
529: case 3 : return 180;
530: case 4 : return 180;
531: case 5 : return 270;
532: case 6 : return 270;
533: case 7 : return 90;
534: case 8 : return 90;
535: }
536: }
537: return false;
538: }
539: ?>
540: