/**
 * Called by ***MaxSpace functions to compute the parameters to be passed to xxCustomyyy functions.
 *
 * @param int $width maxspace width
 * @param int $height maxspace height
 * @param object $image the image in question
 * @param bool $thumb true if for a thumbnail
 */
function getMaxSpaceContainer(&$width, &$height, $image, $thumb = false)
{
    global $_zp_gallery;
    $upscale = getOption('image_allow_upscale');
    $imagename = $image->filename;
    if (!isImagePhoto($image) & $thumb) {
        $imgfile = $image->getThumbImageFile();
        $image = zp_imageGet($imgfile);
        $s_width = zp_imageWidth($image);
        $s_height = zp_imageHeight($image);
    } else {
        $s_width = $image->get('width');
        if ($s_width == 0) {
            $s_width = max($width, $height);
        }
        $s_height = $image->get('height');
        if ($s_height == 0) {
            $s_height = max($width, $height);
        }
    }
    $newW = round($height / $s_height * $s_width);
    $newH = round($width / $s_width * $s_height);
    if (DEBUG_IMAGE) {
        debugLog("getMaxSpaceContainer({$width}, {$height}, {$imagename}, {$thumb}): \$s_width={$s_width}; \$s_height={$s_height}; \$newW={$newW}; \$newH={$newH}; \$upscale={$upscale};");
    }
    if ($newW > $width) {
        if ($upscale || $s_height > $newH) {
            $height = $newH;
        } else {
            $height = $s_height;
            $width = $s_width;
        }
    } else {
        if ($upscale || $s_width > $newW) {
            $width = $newW;
        } else {
            $height = $s_height;
            $width = $s_width;
        }
    }
}
Exemple #2
0
 } else {
     //	have to create the image
     $iMutex = new zpMutex('i', getOption('imageProcessorConcurrency'));
     $iMutex->lock();
     $newim = zp_imageGet($image_path);
     if ($rotate) {
         $newim = zp_rotateImage($newim, $rotate);
     }
     if ($watermark_use_image) {
         $watermark_image = getWatermarkPath($watermark_use_image);
         if (!file_exists($watermark_image)) {
             $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
         }
         $offset_h = getOption('watermark_h_offset') / 100;
         $offset_w = getOption('watermark_w_offset') / 100;
         $watermark = zp_imageGet($watermark_image);
         $watermark_width = zp_imageWidth($watermark);
         $watermark_height = zp_imageHeight($watermark);
         $imw = zp_imageWidth($newim);
         $imh = zp_imageHeight($newim);
         $percent = getOption('watermark_scale') / 100;
         $r = sqrt($imw * $imh * $percent / ($watermark_width * $watermark_height));
         if (!getOption('watermark_allow_upscale')) {
             $r = min(1, $r);
         }
         $nw = round($watermark_width * $r);
         $nh = round($watermark_height * $r);
         if ($nw != $watermark_width || $nh != $watermark_height) {
             $watermark = zp_imageResizeAlpha($watermark, $nw, $nh);
         }
         // Position Overlay in Bottom Right
/**
 * Copy a theme directory to create a new custom theme
 *
 * @param $source source directory
 * @param $target target directory
 * @return bool|string either true or an error message
 * @author Ozh
 * @since 1.3
 */
function copyThemeDirectory($source, $target, $newname)
{
    global $_zp_current_admin_obj;
    $message = true;
    $source = SERVERPATH . '/themes/' . internalToFilesystem($source);
    $target = SERVERPATH . '/themes/' . internalToFilesystem($target);
    // If the target theme already exists, nothing to do.
    if (is_dir($target)) {
        return gettext('Cannot create new theme.') . ' ' . sprintf(gettext('Directory “%s” already exists!'), basename($target));
    }
    // If source dir is missing, exit too
    if (!is_dir($source)) {
        return gettext('Cannot create new theme.') . ' ' . sprintf(gettext('Cannot find theme directory “%s” to copy!'), basename($source));
    }
    // We must be able to write to the themes dir.
    if (!is_writable(dirname($target))) {
        return gettext('Cannot create new theme.') . ' ' . gettext('The <tt>/themes</tt> directory is not writable!');
    }
    // We must be able to create the directory
    if (!mkdir($target, FOLDER_MOD)) {
        return gettext('Cannot create new theme.') . ' ' . gettext('Could not create directory for the new theme');
    }
    @chmod($target, FOLDER_MOD);
    // Get a list of files to copy: get all files from the directory, remove those containing '/.svn/'
    $source_files = array_filter(listDirectoryFiles($source), create_function('$str', 'return strpos($str, "/.svn/") === false;'));
    // Determine nested (sub)directories structure to create: go through each file, explode path on "/"
    // and collect every unique directory
    $dirs_to_create = array();
    foreach ($source_files as $path) {
        $path = explode('/', dirname(str_replace($source . '/', '', $path)));
        $dirs = '';
        foreach ($path as $subdir) {
            if ($subdir == '.svn' or $subdir == '.') {
                continue 2;
            }
            $dirs = "{$dirs}/{$subdir}";
            $dirs_to_create[$dirs] = $dirs;
        }
    }
    // Create new directory structure
    foreach ($dirs_to_create as $dir) {
        mkdir("{$target}/{$dir}", FOLDER_MOD);
        @chmod("{$target}/{$dir}", FOLDER_MOD);
    }
    // Now copy every file
    foreach ($source_files as $file) {
        $newfile = str_replace($source, $target, $file);
        if (!copy("{$file}", "{$newfile}")) {
            return sprintf(gettext("An error occurred while copying files. Please delete manually the new theme directory “%s” and retry or copy files manually."), basename($target));
        }
        @chmod("{$newfile}", FOLDER_MOD);
    }
    // Rewrite the theme header.
    if (file_exists($target . '/theme_description.php')) {
        $theme_description = array();
        require $target . '/theme_description.php';
        $theme_description['desc'] = sprintf(gettext('Your theme, based on theme %s'), $theme_description['name']);
    } else {
        $theme_description['desc'] = gettext('Your theme');
    }
    $theme_description['name'] = $newname;
    $theme_description['author'] = $_zp_current_admin_obj->getUser();
    $theme_description['version'] = '1.0';
    $theme_description['date'] = date('Y-m-d H:m:s', time());
    $description = sprintf('<' . '?php
				// Theme definition file
				$theme_description["name"] = "%s";
				$theme_description["author"] = "%s";
				$theme_description["version"] = "%s";
				$theme_description["date"] = "%s";
				$theme_description["desc"] = "%s";
				?' . '>', html_encode($theme_description['name']), html_encode($theme_description['author']), html_encode($theme_description['version']), html_encode($theme_description['date']), html_encode($theme_description['desc']));
    $f = fopen($target . '/theme_description.php', 'w');
    if ($f !== FALSE) {
        @fwrite($f, $description);
        fclose($f);
        $message = gettext('New custom theme created successfully!');
    } else {
        $message = gettext('New custom theme created, but its description could not be updated');
    }
    // Make a slightly custom theme image
    if (file_exists("{$target}/theme.png")) {
        $themeimage = "{$target}/theme.png";
    } else {
        if (file_exists("{$target}/theme.gif")) {
            $themeimage = "{$target}/theme.gif";
        } else {
            if (file_exists("{$target}/theme.jpg")) {
                $themeimage = "{$target}/theme.jpg";
            } else {
                $themeimage = false;
            }
        }
    }
    if ($themeimage) {
        if ($im = zp_imageGet($themeimage)) {
            $x = zp_imageWidth($im) / 2 - 45;
            $y = zp_imageHeight($im) / 2 - 10;
            $text = "CUSTOM COPY";
            $font = zp_imageLoadFont();
            $ink = zp_colorAllocate($im, 0xff, 0xff, 0xff);
            // create a blueish overlay
            $overlay = zp_createImage(zp_imageWidth($im), zp_imageHeight($im));
            $back = zp_colorAllocate($overlay, 0x60, 0x60, 0x90);
            zp_imageFill($overlay, 0, 0, $back);
            // Merge theme image and overlay
            zp_imageMerge($im, $overlay, 0, 0, 0, 0, zp_imageWidth($im), zp_imageHeight($im), 45);
            // Add text
            zp_writeString($im, $font, $x - 1, $y - 1, $text, $ink);
            zp_writeString($im, $font, $x + 1, $y + 1, $text, $ink);
            zp_writeString($im, $font, $x, $y, $text, $ink);
            // Save new theme image
            zp_imageOutput($im, 'png', $themeimage);
        }
    }
    return $message;
}
Exemple #4
0
if (!$album->isMyItem(ALBUM_RIGHTS)) {
    // prevent nefarious access to this page.
    if (!zp_apply_filter('admin_managed_albums_access', false, $return)) {
        header('Location: ' . FULLWEBPATH . '/' . ZENFOLDER . '/admin.php?from=' . $return);
        exitZP();
    }
}
// get what image side is being used for resizing
$use_side = getOption('image_use_side');
// get full width and height
$albumobj = newAlbum($albumname);
$imageobj = newImage($albumobj, $imagename);
if (isImagePhoto($imageobj)) {
    $imgpath = $imageobj->localpath;
    $imagepart = basename($imgpath);
    $timg = zp_imageGet($imgpath);
    $width = $imageobj->getWidth();
    $height = $imageobj->getHeight();
} else {
    die(gettext('attempt to crop an object which is not an image.'));
}
// get appropriate $sizedwidth and $sizedheight
switch ($use_side) {
    case 'longest':
        $size = min(400, $width, $height);
        if ($width >= $height) {
            $sr = $size / $width;
            $sizedwidth = $size;
            $sizedheight = round($height / $width * $size);
        } else {
            $sr = $size / $height;
/**
 * Creates the cache folder version of the image, including watermarking
 *
 * @param string $newfilename the name of the file when it is in the cache
 * @param string $imgfile the image name
 * @param array $args the cropping arguments
 * @param bool $allow_watermark set to true if image may be watermarked
 * @param string $theme the current theme
 * @param string $album the album containing the image
 */
function cacheImage($newfilename, $imgfile, $args, $allow_watermark = false, $theme, $album)
{
    @(list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop, $thumbstandin, $passedWM, $adminrequest, $effects) = $args);
    // Set the config variables for convenience.
    $image_use_side = getOption('image_use_side');
    $upscale = getOption('image_allow_upscale');
    $allowscale = true;
    $sharpenthumbs = getOption('thumb_sharpen');
    $sharpenimages = getOption('image_sharpen');
    $id = NULL;
    $watermark_use_image = getAlbumInherited($album, 'watermark', $id);
    if (empty($watermark_use_image)) {
        $watermark_use_image = IMAGE_WATERMARK;
    }
    if (!$effects) {
        if ($thumb && getOption('thumb_gray')) {
            $effects = 'gray';
        } else {
            if (getOption('image_gray')) {
                $effects = 'gray';
            }
        }
    }
    $newfile = SERVERCACHE . $newfilename;
    if (DEBUG_IMAGE) {
        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};");
    }
    // Check for the source image.
    if (!file_exists($imgfile) || !is_readable($imgfile)) {
        imageError(gettext('Image not found or is unreadable.'), 'err-imagenotfound.png');
    }
    $rotate = false;
    if (zp_imageCanRotate() && getOption('auto_rotate')) {
        $rotate = getImageRotation($imgfile);
    }
    if ($im = zp_imageGet($imgfile)) {
        if ($rotate) {
            $im = zp_rotateImage($im, $rotate);
        }
        $w = zp_imageWidth($im);
        $h = zp_imageHeight($im);
        // Give the sizing dimension to $dim
        $ratio_in = '';
        $ratio_out = '';
        $crop = $crop || $cw != 0 || $ch != 0;
        if (!empty($size)) {
            $dim = $size;
            $width = $height = false;
            if ($crop) {
                $dim = $size;
                if (!$ch) {
                    $ch = $size;
                }
                if (!$cw) {
                    $cw = $size;
                }
            }
        } else {
            if (!empty($width) && !empty($height)) {
                $ratio_in = $h / $w;
                $ratio_out = $height / $width;
                if ($ratio_in > $ratio_out) {
                    // image is taller than desired, $height is the determining factor
                    $thumb = true;
                    $dim = $width;
                    if (!$ch) {
                        $ch = $height;
                    }
                } else {
                    // image is wider than desired, $width is the determining factor
                    $dim = $height;
                    if (!$cw) {
                        $cw = $width;
                    }
                }
            } else {
                if (!empty($width)) {
                    $dim = $width;
                    $size = $height = false;
                } else {
                    if (!empty($height)) {
                        $dim = $height;
                        $size = $width = false;
                    } else {
                        // There's a problem up there somewhere...
                        imageError(gettext("Unknown error! Please report to the developers at <a href=\"http://www.zenphoto.org/\">www.zenphoto.org</a>"), 'err-imagegeneral.png');
                    }
                }
            }
        }
        $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim);
        list($neww, $newh) = $sizes;
        if (DEBUG_IMAGE) {
            debugLog("cacheImage:" . basename($imgfile) . ": \$size={$size}, \$width={$width}, \$height={$height}, \$w={$w}; \$h={$h}; \$cw={$cw}, " . "\$ch={$ch}, \$cx={$cx}, \$cy={$cy}, \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$newh={$newh}, \$neww={$neww}, \$dim={$dim}, " . "\$ratio_in={$ratio_in}, \$ratio_out={$ratio_out} \$upscale={$upscale} \$rotate={$rotate} \$effects={$effects}");
        }
        if (!$upscale && $newh >= $h && $neww >= $w) {
            // image is the same size or smaller than the request
            $neww = $w;
            $newh = $h;
            $allowscale = false;
            if ($crop) {
                if ($width > $neww) {
                    $width = $neww;
                }
                if ($height > $newh) {
                    $height = $newh;
                }
            }
            if (DEBUG_IMAGE) {
                debugLog("cacheImage:no upscale " . basename($imgfile) . ":  \$newh={$newh}, \$neww={$neww}, \$crop={$crop}, \$thumb={$thumb}, \$rotate={$rotate}, watermark=" . $watermark_use_image);
            }
        }
        // Crop the image if requested.
        if ($crop) {
            if ($cw > $ch) {
                $ir = $ch / $cw;
            } else {
                $ir = $cw / $ch;
            }
            if ($size) {
                $neww = $size;
                $newh = $ir * $size;
            } else {
                $neww = $width;
                $newh = $height;
                if ($neww > $newh) {
                    if ($newh === false) {
                        $newh = $ir * $neww;
                    }
                } else {
                    if ($neww === false) {
                        $neww = $ir * $newh;
                    }
                }
            }
            if (is_null($cx) && is_null($cy)) {
                // scale crop to max of image
                // set crop scale factor
                $cf = 1;
                if ($cw) {
                    $cf = min($cf, $cw / $neww);
                }
                if ($ch) {
                    $cf = min($cf, $ch / $newh);
                }
                //	set the image area of the crop (use the most image possible, rule of thirds positioning)
                if (!$cw || $w / $cw * $ch > $h) {
                    $cw = round($h / $ch * $cw * $cf);
                    $ch = round($h * $cf);
                    $cx = round(($w - $cw) / 3);
                } else {
                    $ch = round($w / $cw * $ch * $cf);
                    $cw = round($w * $cf);
                    $cy = round(($h - $ch) / 3);
                }
            } else {
                // custom crop
                if (!$cw || $cw > $w) {
                    $cw = $w;
                }
                if (!$ch || $ch > $h) {
                    $ch = $h;
                }
            }
            // force the crop to be within the image
            if ($cw + $cx > $w) {
                $cx = $w - $cw;
            }
            if ($cx < 0) {
                $cw = $cw + $cx;
                $cx = 0;
            }
            if ($ch + $cy > $h) {
                $cy = $h - $ch;
            }
            if ($cy < 0) {
                $ch = $ch + $cy;
                $cy = 0;
            }
            if (DEBUG_IMAGE) {
                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}");
            }
            $newim = zp_createImage($neww, $newh);
            zp_resampleImage($newim, $im, 0, 0, $cx, $cy, $neww, $newh, $cw, $ch);
        } else {
            if ($allowscale) {
                $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim);
                list($neww, $newh) = $sizes;
            }
            if (DEBUG_IMAGE) {
                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};");
            }
            $newim = zp_createImage($neww, $newh);
            zp_resampleImage($newim, $im, 0, 0, 0, 0, $neww, $newh, $w, $h);
        }
        $imgEffects = explode(',', $effects);
        if (in_array('gray', $imgEffects)) {
            zp_imageGray($newim);
        }
        if ($thumb && $sharpenthumbs || !$thumb && $sharpenimages) {
            zp_imageUnsharpMask($newim, getOption('sharpen_amount'), getOption('sharpen_radius'), getOption('sharpen_threshold'));
        }
        $watermark_image = false;
        if ($passedWM) {
            if ($passedWM != NO_WATERMARK) {
                $watermark_image = getWatermarkPath($passedWM);
                if (!file_exists($watermark_image)) {
                    $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
                }
            }
        } else {
            if ($allow_watermark) {
                $watermark_image = $watermark_use_image;
                if ($watermark_image) {
                    if ($watermark_image != NO_WATERMARK) {
                        $watermark_image = getWatermarkPath($watermark_image);
                        if (!file_exists($watermark_image)) {
                            $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
                        }
                    }
                }
            }
        }
        if ($watermark_image) {
            $offset_h = getOption('watermark_h_offset') / 100;
            $offset_w = getOption('watermark_w_offset') / 100;
            $watermark = zp_imageGet($watermark_image);
            $watermark_width = zp_imageWidth($watermark);
            $watermark_height = zp_imageHeight($watermark);
            $imw = zp_imageWidth($newim);
            $imh = zp_imageHeight($newim);
            $nw = sqrt($imw * $imh * $percent * ($watermark_width / $watermark_height));
            $nh = $nw * ($watermark_height / $watermark_width);
            $percent = getOption('watermark_scale') / 100;
            $r = sqrt($imw * $imh * $percent / ($watermark_width * $watermark_height));
            if (!getOption('watermark_allow_upscale')) {
                $r = min(1, $r);
            }
            $nw = round($watermark_width * $r);
            $nh = round($watermark_height * $r);
            if ($nw != $watermark_width || $nh != $watermark_height) {
                $watermark = zp_imageResizeAlpha($watermark, $nw, $nh);
            }
            // Position Overlay in Bottom Right
            $dest_x = max(0, floor(($imw - $nw) * $offset_w));
            $dest_y = max(0, floor(($imh - $nh) * $offset_h));
            if (DEBUG_IMAGE) {
                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}");
            }
            zp_copyCanvas($newim, $watermark, $dest_x, $dest_y, 0, 0, $nw, $nh);
            zp_imageKill($watermark);
        }
        // Create the cached file (with lots of compatibility)...
        mkdir_recursive(dirname($newfile));
        if (zp_imageOutput($newim, getSuffix($newfile), $newfile, $quality)) {
            //	successful save of cached image
            if (getOption('ImbedIPTC') && getSuffix($newfilename) == 'jpg') {
                // the imbed function works only with JPEG images
                $iptc_data = zp_imageIPTC($imgfile);
                if (empty($iptc_data)) {
                    global $_zp_extra_filetypes;
                    //	because we are doing the require in a function!
                    if (!$_zp_extra_filetypes) {
                        $_zp_extra_filetypes = array();
                    }
                    require_once dirname(__FILE__) . '/functions.php';
                    //	it is ok to increase memory footprint now since the image processing is complete
                    $gallery = new Gallery();
                    $iptc = array('1#090' => chr(0x1b) . chr(0x25) . chr(0x47), '2#115' => $gallery->getTitle());
                    $imgfile = str_replace(ALBUM_FOLDER_SERVERPATH, '', $imgfile);
                    $imagename = basename($imgfile);
                    $albumname = dirname($imgfile);
                    $image = newImage(new Album(new Gallery(), $albumname), $imagename);
                    $copyright = $image->getCopyright();
                    if (empty($copyright)) {
                        $copyright = getOption('default_copyright');
                    }
                    if (!empty($copyright)) {
                        $iptc['2#116'] = $copyright;
                    }
                    $credit = $image->getCredit();
                    if (!empty($credit)) {
                        $iptc['2#110'] = $credit;
                    }
                    foreach ($iptc as $tag => $string) {
                        $tag_parts = explode('#', $tag);
                        $iptc_data .= iptc_make_tag($tag_parts[0], $tag_parts[1], $string);
                    }
                } else {
                    if (GRAPHICS_LIBRARY == 'Imagick' && IMAGICK_RETAIN_PROFILES) {
                        //	Imageick has preserved the metadata
                        $iptc_data = false;
                    }
                }
                if ($iptc_data) {
                    $content = iptcembed($iptc_data, $newfile);
                    $fw = fopen($newfile, 'w');
                    fwrite($fw, $content);
                    fclose($fw);
                    clearstatcache();
                }
            }
            if (DEBUG_IMAGE) {
                debugLog('Finished:' . basename($imgfile));
            }
        } else {
            if (DEBUG_IMAGE) {
                debugLog('cacheImage: failed to create ' . $newfile);
            }
        }
        @chmod($newfile, 0666 & CHMOD_VALUE);
        zp_imageKill($newim);
        zp_imageKill($im);
    }
}
Exemple #6
0
}
$font = zp_imageLoadFont($fontname, getOption('zenphoto_captcha_font_size'));
$pallet = array(array('R' => 16, 'G' => 110, 'B' => 3), array('R' => 132, 'G' => 4, 'B' => 16), array('R' => 103, 'G' => 3, 'B' => 143), array('R' => 143, 'G' => 32, 'B' => 3), array('R' => 143, 'G' => 38, 'B' => 48), array('R' => 0, 'G' => 155, 'B' => 18));
$fw = zp_imageFontWidth($font);
$w = $fw * $len + 2;
$h = $fh = zp_imagefontheight($font);
$kerning = min(4, floor($fw / 2) - 1);
$leading = $fh - 4;
$ink = $lead = $kern = array();
for ($i = 0; $i < $len; $i++) {
    $lead[$i] = rand(2, $leading);
    $h = max($h, $fh + $lead[$i] + 2);
    $kern[$i] = rand(2, $kerning);
    $w = $w + $kern[$i];
    $p[$i] = $pallet[rand(0, 5)];
}
$image = zp_createImage($w, $h);
$background = zp_imageGet(SERVERPATH . '/' . ZENFOLDER . '/images/captcha_background.png');
zp_copyCanvas($image, $background, 0, 0, rand(0, 9), rand(0, 9), $w, $h);
$l = rand(2, $kerning);
for ($i = 0; $i < $len; $i++) {
    $ink = zp_colorAllocate($image, $p[$i]['R'], $p[$i]['G'], $p[$i]['B']);
    zp_writeString($image, $font, $l, $lead[$i], $string[$i], $ink);
    $l = $l + $fw + $kern[$i];
}
$rectangle = zp_colorAllocate($image, 48, 57, 85);
zp_drawRectangle($image, 0, 0, $w - 1, $h - 1, $rectangle);
zp_imageOutput($image, 'png', NULL);
?>

/**
 * Creates the cache folder version of the image, including watermarking
 *
 * @param string $newfilename the name of the file when it is in the cache
 * @param string $imgfile the image name
 * @param array $args the cropping arguments
 * @param bool $allow_watermark set to true if image may be watermarked
 * @param string $theme the current theme
 * @param string $album the album containing the image
 */
function cacheImage($newfilename, $imgfile, $args, $allow_watermark = false, $theme, $album)
{
    global $_zp_gallery;
    try {
        @(list($size, $width, $height, $cw, $ch, $cx, $cy, $quality, $thumb, $crop, $thumbstandin, $passedWM, $adminrequest, $effects) = $args);
        // Set the config variables for convenience.
        $image_use_side = getOption('image_use_side');
        $upscale = getOption('image_allow_upscale');
        $allowscale = true;
        $sharpenthumbs = getOption('thumb_sharpen');
        $sharpenimages = getOption('image_sharpen');
        $id = $im = NULL;
        $watermark_use_image = getAlbumInherited($album, 'watermark', $id);
        if (empty($watermark_use_image)) {
            $watermark_use_image = IMAGE_WATERMARK;
        }
        if (!$effects) {
            if ($thumb && getOption('thumb_gray')) {
                $effects = 'gray';
            } else {
                if (getOption('image_gray')) {
                    $effects = 'gray';
                }
            }
        }
        $newfile = SERVERCACHE . $newfilename;
        mkdir_recursive(dirname($newfile), FOLDER_MOD);
        if (DEBUG_IMAGE) {
            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});");
        }
        // Check for the source image.
        if (!file_exists($imgfile) || !is_readable($imgfile)) {
            imageError('404 Not Found', sprintf(gettext('Image %s not found or is unreadable.'), filesystemToInternal($imgfile)), 'err-imagenotfound.png');
        }
        $rotate = false;
        if (zp_imageCanRotate()) {
            $rotate = getImageRotation($imgfile);
        }
        $s = getSuffix($imgfile);
        if (function_exists('exif_thumbnail') && getOption('use_embedded_thumb') && ($s == 'jpg' || $s == 'jpeg')) {
            $im = exif_thumbnail($imgfile, $tw, $th, $tt);
            if ($im) {
                if ($size) {
                    $big_enough = $tw >= $size && $th >= $size;
                } else {
                    $big_enough = $tw >= $width && $th >= $height;
                }
                if ($big_enough) {
                    $im = zp_imageFromString($im);
                    if (DEBUG_IMAGE && $im) {
                        debugLog(sprintf(gettext('Using %1$ux%2$u %3$s thumbnail image.'), $tw, $th, image_type_to_mime_type($tt)));
                    }
                } else {
                    $im = false;
                }
            } else {
                $im = false;
            }
        }
        if (!$im) {
            $im = zp_imageGet($imgfile);
        }
        if (!$im) {
            imageError('404 Not Found', sprintf(gettext('Image %s not renderable (imageGet).'), filesystemToInternal($imgfile)), 'err-failimage.png');
        }
        if ($rotate) {
            if (DEBUG_IMAGE) {
                debugLog("cacheImage:rotate->{$rotate}");
            }
            $im = zp_rotateImage($im, $rotate);
            if (!$im) {
                imageError('404 Not Found', sprintf(gettext('Image %s not rotatable.'), filesystemToInternal($imgfile)), 'err-failimage.png');
            }
        }
        $w = zp_imageWidth($im);
        $h = zp_imageHeight($im);
        // Give the sizing dimension to $dim
        $ratio_in = '';
        $ratio_out = '';
        $crop = $crop || $cw != 0 || $ch != 0;
        if (!empty($size)) {
            $dim = $size;
            if ($crop) {
                $dim = $size;
                if (!$ch) {
                    $ch = $size;
                }
                if (!$cw) {
                    $cw = $size;
                }
                $width = $cw;
                $height = $ch;
                $size = false;
            } else {
                $width = $height = false;
            }
        } else {
            if (!empty($width) && !empty($height)) {
                $ratio_in = $h / $w;
                $ratio_out = $height / $width;
                if ($ratio_in > $ratio_out) {
                    // image is taller than desired, $height is the determining factor
                    $thumb = true;
                    $dim = $width;
                    if (!$ch) {
                        $ch = $height;
                    }
                } else {
                    // image is wider than desired, $width is the determining factor
                    $dim = $height;
                    if (!$cw) {
                        $cw = $width;
                    }
                }
            } else {
                if (!empty($width)) {
                    $dim = $width;
                    $size = $height = false;
                } else {
                    if (!empty($height)) {
                        $dim = $height;
                        $size = $width = false;
                    } else {
                        // There's a problem up there somewhere...
                        imageError('404 Not Found', sprintf(gettext('Unknown error processing %s! Please report to the <a href="' . GITHUB . '/issues">developers</a>'), filesystemToInternal($imgfile)), 'err-imagegeneral.png');
                    }
                }
            }
        }
        $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim);
        list($neww, $newh) = $sizes;
        if (DEBUG_IMAGE) {
            debugLog("cacheImage:" . basename($imgfile) . ": \$size={$size}, \$width={$width}, \$height={$height}, \$w={$w}; \$h={$h}; \$cw={$cw}, " . "\$ch={$ch}, \$cx={$cx}, \$cy={$cy}, \$quality={$quality}, \$thumb={$thumb}, \$crop={$crop}, \$newh={$newh}, \$neww={$neww}, \$dim={$dim}, " . "\$ratio_in={$ratio_in}, \$ratio_out={$ratio_out} \$upscale={$upscale} \$rotate={$rotate} \$effects={$effects}");
        }
        if (!$upscale && $newh >= $h && $neww >= $w) {
            // image is the same size or smaller than the request
            $neww = $w;
            $newh = $h;
            $allowscale = false;
            if ($crop) {
                if ($width > $neww) {
                    $width = $neww;
                }
                if ($height > $newh) {
                    $height = $newh;
                }
            }
            if (DEBUG_IMAGE) {
                debugLog("cacheImage:no upscale " . basename($imgfile) . ":  \$newh={$newh}, \$neww={$neww}, \$crop={$crop}, \$thumb={$thumb}, \$rotate={$rotate}, watermark=" . $watermark_use_image);
            }
        }
        $watermark_image = false;
        if ($passedWM) {
            if ($passedWM != NO_WATERMARK) {
                $watermark_image = getWatermarkPath($passedWM);
                if (!file_exists($watermark_image)) {
                    $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
                }
            }
        } else {
            if ($allow_watermark) {
                $watermark_image = $watermark_use_image;
                if ($watermark_image) {
                    if ($watermark_image != NO_WATERMARK) {
                        $watermark_image = getWatermarkPath($watermark_image);
                        if (!file_exists($watermark_image)) {
                            $watermark_image = SERVERPATH . '/' . ZENFOLDER . '/images/imageDefault.png';
                        }
                    }
                }
            }
        }
        // Crop the image if requested.
        if ($crop) {
            if ($cw > $ch) {
                $ir = $ch / $cw;
            } else {
                $ir = $cw / $ch;
            }
            if ($size) {
                $neww = $size;
                $newh = $ir * $size;
            } else {
                $neww = $width;
                $newh = $height;
                if ($neww > $newh) {
                    if ($newh === false) {
                        $newh = $ir * $neww;
                    }
                } else {
                    if ($neww === false) {
                        $neww = $ir * $newh;
                    }
                }
            }
            if (is_null($cx) && is_null($cy)) {
                // scale crop to max of image
                // set crop scale factor
                $cf = 1;
                if ($cw) {
                    $cf = min($cf, $cw / $neww);
                }
                if ($ch) {
                    $cf = min($cf, $ch / $newh);
                }
                //	set the image area of the crop (use the most image possible, rule of thirds positioning)
                if (!$cw || $w / $cw * $ch > $h) {
                    $cw = round($h / $ch * $cw * $cf);
                    $ch = round($h * $cf);
                    $cx = round(($w - $cw) / 3);
                } else {
                    $ch = round($w / $cw * $ch * $cf);
                    $cw = round($w * $cf);
                    $cy = round(($h - $ch) / 3);
                }
            } else {
                // custom crop
                if (!$cw || $cw > $w) {
                    $cw = $w;
                }
                if (!$ch || $ch > $h) {
                    $ch = $h;
                }
            }
            // force the crop to be within the image
            if ($cw + $cx > $w) {
                $cx = $w - $cw;
            }
            if ($cx < 0) {
                $cw = $cw + $cx;
                $cx = 0;
            }
            if ($ch + $cy > $h) {
                $cy = $h - $ch;
            }
            if ($cy < 0) {
                $ch = $ch + $cy;
                $cy = 0;
            }
            if (DEBUG_IMAGE) {
                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}");
            }
            $newim = zp_createImage($neww, $newh);
            if (!zp_resampleImage($newim, $im, 0, 0, $cx, $cy, $neww, $newh, $cw, $ch)) {
                imageError('404 Not Found', sprintf(gettext('Image %s not renderable (resample).'), filesystemToInternal($imgfile)), 'err-failimage.png');
            }
        } else {
            if ($newh >= $h && $neww >= $w && !$rotate && !$effects && !$watermark_image && (!$upscale || $newh == $h && $neww == $w)) {
                // we can just use the original!
                if (SYMLINK && @symlink($imgfile, $newfile)) {
                    if (DEBUG_IMAGE) {
                        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};");
                    }
                    clearstatcache();
                    return true;
                } else {
                    if (@copy($imgfile, $newfile)) {
                        if (DEBUG_IMAGE) {
                            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};");
                        }
                        clearstatcache();
                        return true;
                    }
                }
            }
            if ($allowscale) {
                $sizes = propSizes($size, $width, $height, $w, $h, $thumb, $image_use_side, $dim);
                list($neww, $newh) = $sizes;
            }
            if (DEBUG_IMAGE) {
                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};");
            }
            $newim = zp_createImage($neww, $newh);
            if (!zp_resampleImage($newim, $im, 0, 0, 0, 0, $neww, $newh, $w, $h)) {
                imageError('404 Not Found', sprintf(gettext('Image %s not renderable (resample).'), filesystemToInternal($imgfile)), 'err-failimage.png');
            }
            if ($thumb && $sharpenthumbs || !$thumb && $sharpenimages) {
                if (!zp_imageUnsharpMask($newim, getOption('sharpen_amount'), getOption('sharpen_radius'), getOption('sharpen_threshold'))) {
                    imageError('404 Not Found', sprintf(gettext('Image %s not renderable (unsharp).'), filesystemToInternal($imgfile)), 'err-failimage.png');
                }
            }
        }
        $imgEffects = explode(',', $effects);
        if (in_array('gray', $imgEffects)) {
            zp_imageGray($newim);
        }
        if ($watermark_image) {
            $offset_h = getOption('watermark_h_offset') / 100;
            $offset_w = getOption('watermark_w_offset') / 100;
            $percent = getOption('watermark_scale') / 100;
            $watermark = zp_imageGet($watermark_image);
            if (!$watermark) {
                imageError('404 Not Found', sprintf(gettext('Watermark %s not renderable.'), $watermark_image), 'err-failimage.png');
            }
            $watermark_width = zp_imageWidth($watermark);
            $watermark_height = zp_imageHeight($watermark);
            $imw = zp_imageWidth($newim);
            $imh = zp_imageHeight($newim);
            $nw = sqrt($imw * $imh * $percent * ($watermark_width / $watermark_height));
            $nh = $nw * ($watermark_height / $watermark_width);
            $r = sqrt($imw * $imh * $percent / ($watermark_width * $watermark_height));
            if (!getOption('watermark_allow_upscale')) {
                $r = min(1, $r);
            }
            $nw = round($watermark_width * $r);
            $nh = round($watermark_height * $r);
            if ($nw != $watermark_width || $nh != $watermark_height) {
                $watermark = zp_imageResizeAlpha($watermark, $nw, $nh);
                if (!$watermark) {
                    imageError('404 Not Found', sprintf(gettext('Watermark %s not resizeable.'), $watermark_image), 'err-failimage.png');
                }
            }
            // Position Overlay in Bottom Right
            $dest_x = max(0, floor(($imw - $nw) * $offset_w));
            $dest_y = max(0, floor(($imh - $nh) * $offset_h));
            if (DEBUG_IMAGE) {
                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}");
            }
            if (!zp_copyCanvas($newim, $watermark, $dest_x, $dest_y, 0, 0, $nw, $nh)) {
                imageError('404 Not Found', sprintf(gettext('Image %s not renderable (copycanvas).'), filesystemToInternal($imgfile)), 'err-failimage.png');
            }
            zp_imageKill($watermark);
        }
        // Create the cached file (with lots of compatibility)...
        @chmod($newfile, 0777);
        if (zp_imageOutput($newim, getSuffix($newfile), $newfile, $quality)) {
            //	successful save of cached image
            if (getOption('ImbedIPTC') && getSuffix($newfilename) == 'jpg' && GRAPHICS_LIBRARY != 'Imagick') {
                // the imbed function works only with JPEG images
                global $_zp_images_classes;
                //	because we are doing the require in a function!
                require_once dirname(__FILE__) . '/functions.php';
                //	it is ok to increase memory footprint now since the image processing is complete
                $iptc = array('1#090' => chr(0x1b) . chr(0x25) . chr(0x47), '2#115' => $_zp_gallery->getTitle());
                $iptc_data = zp_imageIPTC($imgfile);
                if ($iptc_data) {
                    $iptc_data = iptcparse($iptc_data);
                    if ($iptc_data) {
                        $iptc = array_merge($iptc_data, $iptc);
                    }
                }
                $imgfile = str_replace(ALBUM_FOLDER_SERVERPATH, '', $imgfile);
                $imagename = basename($imgfile);
                $albumname = dirname($imgfile);
                $image = newImage(newAlbum($albumname), $imagename);
                $copyright = $image->getCopyright();
                if (empty($copyright)) {
                    $copyright = getOption('default_copyright');
                }
                if (!empty($copyright)) {
                    $iptc['2#116'] = $copyright;
                }
                $credit = $image->getCredit();
                if (!empty($credit)) {
                    $iptc['2#110'] = $credit;
                }
                $iptc_result = '';
                foreach ($iptc as $tag => $string) {
                    $tag_parts = explode('#', $tag);
                    if (is_array($string)) {
                        foreach ($string as $element) {
                            $iptc_result .= iptc_make_tag($tag_parts[0], $tag_parts[1], $element);
                        }
                    } else {
                        $iptc_result .= iptc_make_tag($tag_parts[0], $tag_parts[1], $string);
                    }
                }
                $content = iptcembed($iptc_result, $newfile);
                $fw = fopen($newfile, 'w');
                fwrite($fw, $content);
                fclose($fw);
                clearstatcache();
            }
            @chmod($newfile, FILE_MOD);
            if (DEBUG_IMAGE) {
                debugLog('Finished:' . basename($imgfile));
            }
        } else {
            if (DEBUG_IMAGE) {
                debugLog('cacheImage: failed to create ' . $newfile);
            }
            imageError('404 Not Found', sprintf(gettext('cacheImage: failed to create %s'), $newfile), 'err-failimage.png');
        }
        @chmod($newfile, FILE_MOD);
        zp_imageKill($newim);
        zp_imageKill($im);
    } catch (Exception $e) {
        debugLog('cacheImage(' . $newfilename . ') exception: ' . $e->getMessage());
        imageError('404 Not Found', sprintf(gettext('cacheImage(%1$s) exception: %2$s'), $newfilename, $e->getMessage()), 'err-failimage.png');
        return false;
    }
    clearstatcache();
    return true;
}