1<?php
2/**
3 * Coppermine Photo Gallery
4 *
5 * v1.0 originally written by Gregory Demar
6 *
7 * @copyright  Copyright (c) 2003-2021 Coppermine Dev Team
8 * @license    GNU General Public License version 3 or later; see LICENSE
9 *
10 * include/picmgmt.php
11 * @since  1.6.10
12 */
13
14defined('IN_COPPERMINE') or die('Not in Coppermine...');
15
16if ($CONFIG['read_iptc_data'] ){
17    include 'include/iptc.inc.php';
18}
19
20// Add a picture to an album
21function add_picture($aid, $filepath, $filename, $position = 0, $title = '', $caption = '', $keywords = '', $user1 = '', $user2 = '', $user3 = '', $user4 = '', $category = 0, $raw_ip = '', $hdr_ip = '', $iwidth = 0, $iheight = 0)
22{
23    global $CONFIG, $USER_DATA, $PIC_NEED_APPROVAL, $CURRENT_PIC_DATA;
24    global $lang_errors, $lang_db_input_php;
25
26    $image = $CONFIG['fullpath'] . $filepath . $filename;
27    $normal = $CONFIG['fullpath'] . $filepath . $CONFIG['normal_pfx'] . $filename;
28    $thumb = $CONFIG['fullpath'] . $filepath . $CONFIG['thumb_pfx'] . $filename;
29    $orig = $CONFIG['fullpath'] . $filepath . $CONFIG['orig_pfx'] . $filename;
30    // $mini = $CONFIG['fullpath'] . $filepath . $CONFIG['mini_pfx'] . $filename;
31    $work_image = $image;
32
33
34    if (!is_known_filetype($image)) {
35        return array('error' => $lang_db_input_php['err_invalid_fext'] . ' ' . $CONFIG['allowed_file_extensions'], 'halt_upload' => 0);
36    } elseif (is_image($filename)) {
37
38        if ($CONFIG['read_iptc_data']) {
39            // read IPTC data
40            $iptc = get_IPTC($image);
41            if (is_array($iptc) && !$title && !$caption && !$keywords) {  //if any of those 3 are filled out we don't want to override them, they may be blank on purpose.
42                $title = (isset($iptc['Headline'])) ? trim($iptc['Headline']) : $title;
43                $caption = (isset($iptc['Caption'])) ? trim($iptc['Caption']) : $caption;
44                $keywords = (isset($iptc['Keywords'])) ? implode($CONFIG['keyword_separator'], $iptc['Keywords']) : $keywords;
45            }
46        }
47
48		if (isset($CONFIG['autorient']) && $CONFIG['autorient'] == 1) {
49			if (function_exists('exif_read_data')) {	// try for the EXIF php extension
50				$exif = @exif_read_data(realpath($image));
51				$ort = $exif && isset($exif['Orientation']) ? $exif['Orientation'] : 0;
52			} else {	// otherwise use Exifer
53				include 'exif.php';
54				$exif = read_exif_data_raw(realpath($image),0);
55				$ort = isset($exif['IFD0']['Orientation']) ? (int)$exif['IFD0']['Orientation'] : 0;
56			}
57			if ($ort > 1) {
58				getImageTool();
59				$imgObj = new imageObject(dirname($image).'/', basename($image));
60				$imgObj->orientImage($ort);
61			}
62		}
63
64        $imagesize = cpg_getimagesize($image);
65
66        // resize picture if it's bigger than the max width or height for uploaded pictures
67        if (max($imagesize[0], $imagesize[1]) > $CONFIG['max_upl_width_height']) {
68            if ((USER_IS_ADMIN && $CONFIG['auto_resize'] == 1) || (!USER_IS_ADMIN && $CONFIG['auto_resize'] > 0)) {
69                $resize_method = $CONFIG['picture_use'] == "thumb" ? ($CONFIG['thumb_use'] == "ex" ? "any" : $CONFIG['thumb_use']) : $CONFIG['picture_use'];
70                resize_image($image, $image, $CONFIG['max_upl_width_height'], $resize_method, 'false');
71                $imagesize = cpg_getimagesize($image);
72            } elseif (USER_IS_ADMIN) {
73                // skip resizing for admin
74                $picture_original_size = true;
75            } else {
76                @unlink($uploaded_pic);
77                $msg = sprintf($lang_db_input_php['err_fsize_too_large'], $CONFIG['max_upl_width_height'], $CONFIG['max_upl_width_height']);
78                return array('error' => $msg, 'halt_upload' => 1);
79            }
80        }
81
82        // create backup of full sized picture if watermark is enabled for full sized pictures
83        if (!file_exists($orig) && $CONFIG['enable_watermark'] == '1' && ($CONFIG['which_files_to_watermark'] == 'both' || $CONFIG['which_files_to_watermark'] == 'original'))  {
84            if (!copy($image, $orig)) {
85                return false;
86            } else {
87                $work_image = $orig;
88            }
89        }
90
91        if (!file_exists($thumb)) {
92            // create thumbnail
93            if (($result = resize_image($work_image, $thumb, $CONFIG['thumb_width'], $CONFIG['thumb_use'], "false", 1)) !== true) {
94                return $result;
95            }
96        }
97
98        if ($CONFIG['make_intermediate'] && cpg_picture_dimension_exceeds_intermediate_limit($imagesize[0], $imagesize[1]) && !file_exists($normal)) {
99            // create intermediate sized picture
100            $resize_method = $CONFIG['picture_use'] == "thumb" ? ($CONFIG['thumb_use'] == "ex" ? "any" : $CONFIG['thumb_use']) : $CONFIG['picture_use'];
101            $watermark = ($CONFIG['enable_watermark'] == '1' && ($CONFIG['which_files_to_watermark'] == 'both' || $CONFIG['which_files_to_watermark'] == 'resized')) ? 'true' : 'false';
102            if (($result = resize_image($work_image, $normal, $CONFIG['picture_width'], $resize_method, $watermark)) !== true) {
103                return $result;
104            }
105        }
106
107        // watermark full sized picture
108        if ($CONFIG['enable_watermark'] == '1' && ($CONFIG['which_files_to_watermark'] == 'both' || $CONFIG['which_files_to_watermark'] == 'original')) {
109            $wm_max_upl_width_height = $picture_original_size ? max($imagesize[0], $imagesize[1]) : $CONFIG['max_upl_width_height']; // use max aspect of original image if it hasn't been resized earlier
110            if (($result = resize_image($work_image, $image, $wm_max_upl_width_height, 'any', 'true')) !== true) {
111                return $result;
112            }
113        }
114    } else {
115        $imagesize[0] = $iwidth;
116        $imagesize[1] = $iheight;
117    }
118
119    clearstatcache();
120
121    $image_filesize = filesize($image);
122    $total_filesize = is_image($filename) ? ($image_filesize + (file_exists($normal) ? filesize($normal) : 0) + filesize($thumb)) : ($image_filesize);
123
124
125    // Test if disk quota exceeded
126    if (!GALLERY_ADMIN_MODE && $USER_DATA['group_quota'] && $category == FIRST_USER_CAT + USER_ID) {
127        $result = cpg_db_query("SELECT sum(total_filesize) FROM {$CONFIG['TABLE_PICTURES']}, {$CONFIG['TABLE_ALBUMS']} WHERE  {$CONFIG['TABLE_PICTURES']}.aid = {$CONFIG['TABLE_ALBUMS']}.aid AND category = '" . (FIRST_USER_CAT + USER_ID) . "'");
128        $record = $result->fetchArray(true);
129        $total_space_used = $record[0];
130
131        if ((($total_space_used + $total_filesize)>>10) > $USER_DATA['group_quota'] ) {
132            @unlink($image);
133            if (is_image($image)) {
134                @unlink($normal);
135                @unlink($thumb);
136            }
137            $msg = $lang_errors['quota_exceeded'] . '<br />&nbsp;<br />' . strtr($lang_errors['quota_exceeded_details'], array('[quota]' => ($USER_DATA['group_quota']), '[space]' => ($total_space_used >> 10)));
138            return array('error' => $msg, 'halt_upload' => 1);
139        }
140    }
141    // Test if picture requires approval
142    if (GALLERY_ADMIN_MODE) {
143        $approved = 'YES';
144    } elseif (!$USER_DATA['priv_upl_need_approval'] && $category == FIRST_USER_CAT + USER_ID) {
145        $approved = 'YES';
146    } elseif (!$USER_DATA['pub_upl_need_approval'] && $category < FIRST_USER_CAT) {
147        $approved = 'YES';
148    } else {
149        $approved = 'NO';
150    }
151    $PIC_NEED_APPROVAL = ($approved == 'NO');
152
153    // User ID is recorded when in admin mode
154    $user_id  = USER_ID;
155
156    // Populate Array to pass to plugins, then to SQL
157    $CURRENT_PIC_DATA['aid'] = $aid;
158    $CURRENT_PIC_DATA['filepath'] = $filepath;
159    $CURRENT_PIC_DATA['filename'] = $filename;
160    $CURRENT_PIC_DATA['filesize'] = $image_filesize;
161    $CURRENT_PIC_DATA['total_filesize'] = $total_filesize;
162    $CURRENT_PIC_DATA['pwidth'] = $imagesize[0];
163    $CURRENT_PIC_DATA['pheight'] = $imagesize[1];
164    $CURRENT_PIC_DATA['owner_id'] = $user_id;
165    $CURRENT_PIC_DATA['title'] = $title;
166    $CURRENT_PIC_DATA['caption'] = $caption;
167    $CURRENT_PIC_DATA['keywords'] = $keywords;
168    $CURRENT_PIC_DATA['approved'] = $approved;
169    $CURRENT_PIC_DATA['user1'] = $user1;
170    $CURRENT_PIC_DATA['user2'] = $user2;
171    $CURRENT_PIC_DATA['user3'] = $user3;
172    $CURRENT_PIC_DATA['user4'] = $user4;
173    $CURRENT_PIC_DATA['pic_raw_ip'] = $raw_ip;
174    $CURRENT_PIC_DATA['pic_hdr_ip'] = $hdr_ip;
175    $CURRENT_PIC_DATA['position'] = $position;
176    $CURRENT_PIC_DATA['guest_token'] = USER_ID == 0 ? cpg_get_guest_token() : '';
177    $CURRENT_PIC_DATA = CPGPluginAPI::filter('add_file_data', $CURRENT_PIC_DATA);
178
179    if (USER_ID > 0 || $CONFIG['allow_guests_enter_file_details'] == 1) {
180        $query = "INSERT INTO {$CONFIG['TABLE_PICTURES']} (aid, filepath, filename, filesize, total_filesize, pwidth, pheight, ctime, owner_id, title, caption, keywords, approved, user1, user2, user3, user4, pic_raw_ip, pic_hdr_ip, position, guest_token) VALUES ('{$CURRENT_PIC_DATA['aid']}', '" . addslashes($CURRENT_PIC_DATA['filepath']) . "', '" . addslashes($CURRENT_PIC_DATA['filename']) . "', '{$CURRENT_PIC_DATA['filesize']}', '{$CURRENT_PIC_DATA['total_filesize']}', '{$CURRENT_PIC_DATA['pwidth']}', '{$CURRENT_PIC_DATA['pheight']}', '" . time() . "', '{$CURRENT_PIC_DATA['owner_id']}', '{$CURRENT_PIC_DATA['title']}', '{$CURRENT_PIC_DATA['caption']}', '{$CURRENT_PIC_DATA['keywords']}', '{$CURRENT_PIC_DATA['approved']}', '{$CURRENT_PIC_DATA['user1']}', '{$CURRENT_PIC_DATA['user2']}', '{$CURRENT_PIC_DATA['user3']}', '{$CURRENT_PIC_DATA['user4']}', '{$CURRENT_PIC_DATA['pic_raw_ip']}', '{$CURRENT_PIC_DATA['pic_hdr_ip']}', '{$CURRENT_PIC_DATA['position']}', '{$CURRENT_PIC_DATA['guest_token']}')";
181    } else  {
182        $query = "INSERT INTO {$CONFIG['TABLE_PICTURES']} (aid, filepath, filename, filesize, total_filesize, pwidth, pheight, ctime, owner_id, title, caption, keywords, approved, user1, user2, user3, user4, pic_raw_ip, pic_hdr_ip, position, guest_token) VALUES ('{$CURRENT_PIC_DATA['aid']}', '" . addslashes($CURRENT_PIC_DATA['filepath']) . "', '" . addslashes($CURRENT_PIC_DATA['filename']) . "', '{$CURRENT_PIC_DATA['filesize']}', '{$CURRENT_PIC_DATA['total_filesize']}', '{$CURRENT_PIC_DATA['pwidth']}', '{$CURRENT_PIC_DATA['pheight']}', '" . time() . "', '{$CURRENT_PIC_DATA['owner_id']}', '', '', '', '{$CURRENT_PIC_DATA['approved']}', '{$CURRENT_PIC_DATA['user1']}', '{$CURRENT_PIC_DATA['user2']}', '{$CURRENT_PIC_DATA['user3']}', '{$CURRENT_PIC_DATA['user4']}', '{$CURRENT_PIC_DATA['pic_raw_ip']}', '{$CURRENT_PIC_DATA['pic_hdr_ip']}', '{$CURRENT_PIC_DATA['position']}', '{$CURRENT_PIC_DATA['guest_token']}')";
183    }
184    $result = cpg_db_query($query);
185
186    // Put the pid in current_pic_data and call the plugin filter for file data success
187    $CURRENT_PIC_DATA['pid'] = cpg_db_last_insert_id();
188    CPGPluginAPI::action('add_file_data_success', $CURRENT_PIC_DATA);
189
190    //return $result;
191    return true;
192}
193
194define("GIS_GIF", 1);
195define("GIS_JPG", 2);
196define("GIS_PNG", 3);
197
198// Add 'edit' directory if it doesn't exist
199// Set access to read+write only
200if (!is_dir($CONFIG['fullpath'].'edit')) {
201    $cpg_umask = umask(0);
202    @mkdir($CONFIG['fullpath'].'edit',0777);
203    umask($cpg_umask);
204    unset($cpg_umask);
205}
206
207/**
208* resize_image()
209*
210* Create a file containing a resized image
211*
212* @param  $src_file the source file
213* @param  $dest_file the destination file
214* @param  $new_size the size of the square within which the new image must fit
215* @param  $method the method used for image resizing
216* @return 'true' in case of success
217*/
218function resize_image($src_file, $dest_file, $new_size, $thumb_use, $watermark="false", $sharpen=0, $media_type="false")
219{
220	$dirn = dirname($src_file) . '/';
221	$filn = basename($src_file);
222	getImageTool();
223	$imgObj = new imageObject($dirn, $filn);
224	return $imgObj->resize_added_image($dest_file, $new_size, $thumb_use, $watermark, $sharpen, $media_type);
225}
226
227
228//function to sharpen images using GD2
229function UnsharpMask($img, $amount, $radius, $threshold)        {
230////////////////////////////////////////////////////////////////////////////////////////////////
231////
232////                  p h p U n s h a r p M a s k
233////
234////        Unsharp mask algorithm by Torstein H�nsi 2003.
235////                 thoensi_at_netcom_dot_no.
236////                   Please leave this notice.
237////
238///////////////////////////////////////////////////////////////////////////////////////////////
239        if ($amount > 500)        $amount = 500;
240        $amount = $amount * 0.016;
241        if ($radius > 50)        $radius = 50;
242        $radius = $radius * 2;
243        if ($threshold > 255)        $threshold = 255;
244
245        $radius = abs(round($radius));         // Only integers make sense.
246        if ($radius == 0) {
247            return $img;
248        }
249        $w = imagesx($img); $h = imagesy($img);
250        $imgCanvas = imagecreatetruecolor($w, $h);
251        $imgCanvas2 = imagecreatetruecolor($w, $h);
252        $imgBlur = imagecreatetruecolor($w, $h);
253        $imgBlur2 = imagecreatetruecolor($w, $h);
254        imagecopy ($imgCanvas, $img, 0, 0, 0, 0, $w, $h);
255        imagecopy ($imgCanvas2, $img, 0, 0, 0, 0, $w, $h);
256
257        for ($i = 0; $i < $radius; $i++)        {
258                imagecopy ($imgBlur, $imgCanvas, 0, 0, 1, 1, $w - 1, $h - 1); // up left
259                imagecopymerge ($imgBlur, $imgCanvas, 1, 1, 0, 0, $w, $h, 50); // down right
260                imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
261                imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 1, $w, $h - 1, 25); // up right
262                imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
263                imagecopymerge ($imgBlur, $imgCanvas, 1, 0, 0, 0, $w, $h, 25); // right
264                imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 20 ); // up
265                imagecopymerge ($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 16.666667); // down
266                imagecopymerge ($imgBlur, $imgCanvas, 0, 0, 0, 0, $w, $h, 50); // center
267                imagecopy ($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h);
268
269                imagecopy ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h);
270                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
271                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
272                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
273                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 33.33333);
274                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 25);
275                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 20 );
276                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 16.666667);
277                imagecopymerge ($imgBlur2, $imgCanvas2, 0, 0, 0, 0, $w, $h, 50);
278                imagecopy ($imgCanvas2, $imgBlur2, 0, 0, 0, 0, $w, $h);
279
280                }
281
282        for ($x = 0; $x < $w; $x++)        { // each row
283                for ($y = 0; $y < $h; $y++)        { // each pixel
284
285                        $rgbOrig = ImageColorAt($imgCanvas2, $x, $y);
286                        $rOrig = (($rgbOrig >> 16) & 0xFF);
287                        $gOrig = (($rgbOrig >> 8) & 0xFF);
288                        $bOrig = ($rgbOrig & 0xFF);
289
290                        $rgbBlur = ImageColorAt($imgCanvas, $x, $y);
291
292                        $rBlur = (($rgbBlur >> 16) & 0xFF);
293                        $gBlur = (($rgbBlur >> 8) & 0xFF);
294                        $bBlur = ($rgbBlur & 0xFF);
295
296                        $rNew = (abs($rOrig - $rBlur) >= $threshold)
297                                ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig))
298                                : $rOrig;
299                        $gNew = (abs($gOrig - $gBlur) >= $threshold)
300                                ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig))
301                                : $gOrig;
302                        $bNew = (abs($bOrig - $bBlur) >= $threshold)
303                                ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig))
304                                : $bOrig;
305
306
307
308                        if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
309                                    $pixCol = ImageColorAllocate($img, $rNew, $gNew, $bNew);
310                                    ImageSetPixel($img, $x, $y, $pixCol);
311                                }
312}
313                }
314
315        imagedestroy($imgCanvas);
316        imagedestroy($imgCanvas2);
317        imagedestroy($imgBlur);
318        imagedestroy($imgBlur2);
319
320        return $img;
321        }
322
323//EOF