diff --git a/contrib/handle_ico/main.php b/contrib/handle_ico/main.php new file mode 100644 index 00000000..90fd90a1 --- /dev/null +++ b/contrib/handle_ico/main.php @@ -0,0 +1,104 @@ + + * Description: Handle windows icons + */ + +class IcoFileHandler extends Extension { + var $theme; + + public function receive_event($event) { + if(is_null($this->theme)) $this->theme = get_theme_object("handle_ico", "IcoFileHandlerTheme"); + + if(is_a($event, 'DataUploadEvent') && $this->supported_ext($event->type) && $this->check_contents($event->tmpname)) { + $hash = $event->hash; + $ha = substr($hash, 0, 2); + if(!move_upload_to_archive($event)) return; + send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); + $image = $this->create_image_from_data("images/$ha/$hash", $event->metadata); + if(is_null($image)) { + $event->veto("Handler failed to create image object from data"); + return; + } + + $iae = new ImageAdditionEvent($event->user, $image); + send_event($iae); + if($iae->vetoed) { + $event->veto($iae->veto_reason); + return; + } + } + + if(is_a($event, 'ThumbnailGenerationEvent') && $this->supported_ext($event->type)) { + $this->create_thumb($event->hash); + } + + if(is_a($event, 'DisplayingImageEvent') && $this->supported_ext($event->image->ext)) { + $this->theme->display_image($event->page, $event->image); + } + } + + private function supported_ext($ext) { + $exts = array("ico", "ani", "cur"); + return array_contains($exts, strtolower($ext)); + } + + private function create_image_from_data($filename, $metadata) { + global $config; + + $image = new Image(); + + $info = ""; + $fp = fopen($filename, "r"); + $header = unpack("snull/stype/scount", fread($fp, 6)); + + $subheader = unpack("cwidth/cheight/ccolours/cnull/splanes/sbpp/lsize/loffset", fread($fp, 16)); + fclose($fp); + + $image->width = $subheader['width']; + $image->height = $subheader['height']; + + $image->filesize = $metadata['size']; + $image->hash = $metadata['hash']; + $image->filename = $metadata['filename']; + $image->ext = $metadata['extension']; + $image->tag_array = tag_explode($metadata['tags']); + $image->source = $metadata['source']; + + return $image; + } + + private function check_contents($file) { + if(!file_exists($file)) return false; + $fp = fopen($file, "r"); + $header = unpack("snull/stype/scount", fread($fp, 6)); + fclose($fp); + return ($header['null'] == 0 && ($header['type'] == 0 || $header['type'] == 1)); + } + + private function create_thumb($hash) { + global $config; + + $ha = substr($hash, 0, 2); + $inname = "images/$ha/$hash"; + $outname = "thumbs/$ha/$hash"; + + $w = $config->get_int("thumb_width"); + $h = $config->get_int("thumb_height"); + $q = $config->get_int("thumb_quality"); + $mem = $config->get_int("thumb_max_memory") / 1024 / 1024; // IM takes memory in MB + + if($config->get_bool("ico_convert")) { + // "-limit memory $mem" broken? + exec("convert {$inname}[0] -geometry {$w}x{$h} -quality {$q} jpg:$outname"); + } + else { + copy($inname, $outname); + } + + return true; + } +} +add_event_listener(new IcoFileHandler()); +?> diff --git a/contrib/handle_ico/theme.php b/contrib/handle_ico/theme.php new file mode 100644 index 00000000..95639ee3 --- /dev/null +++ b/contrib/handle_ico/theme.php @@ -0,0 +1,10 @@ +get_image_link(); + $html = ""; + $page->add_block(new Block("Image", $html, "main", 0)); + } +} +?> diff --git a/contrib/res_limit/main.php b/contrib/res_limit/main.php index f28b0edd..b7141f3a 100644 --- a/contrib/res_limit/main.php +++ b/contrib/res_limit/main.php @@ -15,6 +15,7 @@ class ResolutionLimit extends Extension { $max_w = $config->get_int("upload_max_width", -1); $max_h = $config->get_int("upload_max_height", -1); $ratios = explode(" ", $config->get_string("upload_ratios", "")); + $ratios = array_filter($ratios, "strlen"); $image = $event->image; @@ -27,6 +28,7 @@ class ResolutionLimit extends Extension { $ok = false; foreach($ratios as $ratio) { $parts = explode(":", $ratio); + if(count($parts) < 2) continue; $width = $parts[0]; $height = $parts[1]; if($image->width / $width == $image->height / $height) { diff --git a/core/util.inc.php b/core/util.inc.php index daadb0df..57bbe3db 100644 --- a/core/util.inc.php +++ b/core/util.inc.php @@ -233,6 +233,17 @@ function get_base_href() { } +function move_upload_to_archive($event) { + $hash = $event->hash; + $ha = substr($hash, 0, 2); + if(!copy($event->tmpname, "images/$ha/$hash")) { + $event->veto("Failed to copy file from uploads ({$event->tmpname}) to archive (images/$ha/$hash)"); + return false; + } + return true; +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Debugging functions * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ diff --git a/ext/upload/main.php b/ext/upload/main.php index c97e4808..78af50bb 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -188,7 +188,7 @@ class Upload extends Extension { $event = new DataUploadEvent($user, $tmp_filename, $metadata); send_event($event); if($event->vetoed) { - $this->theme->display_upload_error($page, "Error with ".html_escape($file['name']), + $this->theme->display_upload_error($page, "Error with ".html_escape($url), $event->veto_reason); $ok = false; }