Skip to content
Snippets Groups Projects
Commit 2897ee29 authored by Mike Carper's avatar Mike Carper Committed by Michael Carper
Browse files

Issue #3258684 by mikeytown2: use ghostscript bin vs convert for pdf

parent e3dfe374
Branches
Tags
No related merge requests found
......@@ -9,68 +9,67 @@
* Implements hook_init().
*/
function auc_init() {
module_load_include('inc', 'auc', 'auc.under_hood');
// Quick return.
// Quick return if $_FILES is empty.
if (empty($_FILES)) {
return;
}
module_load_include('inc', 'auc', 'auc.under_hood');
// Eventually have configuration for this.
$conversion_lut = array(
// This will be process with imagemagick tool.
'heic' => array(
// This will be processed with the imagemagick tool.
'heic' => [
'extension' => 'jpg',
'program' => 'imagemagick',
'command' => "%fn% -type optimize -quality 85% -strip 'jpg:%fn%'",
),
'webp' => array(
],
'webp' => [
'extension' => 'jpg',
'program' => 'imagemagick',
'command' => "%fn% -type optimize -quality 85% -strip 'jpg:%fn%'",
),
'psd' => array(
],
'psd' => [
'extension' => 'jpg',
'program' => 'imagemagick',
'command' => "%fn%[0] -background white -flatten -type optimize -quality 85% -strip 'jpg:%fn%'"
),
],
// Converting ai, eps, pdf to png with a 300 dpi and/or 3000x3000 px max
// using ghostscript.
'ai' => array(
'extension' => 'png',
'program' => 'imagemagick',
'command' => "-density %fn% -resize 3000x3000 'png:%fn%'",
),
'eps' => array(
'extension' => 'png',
'program' => 'imagemagick',
'command' => "-density 300 %fn% -resize 3000x3000 'png:%fn%'",
),
'pdf' => array(
'extension' => 'png',
'program' => 'imagemagick',
'command' => "-density 300 -depth 8 -quality 85 %fn% -resize 3000x3000 'png:%fn%'",
),
// Convert ai, eps, & pdf files to 85% jpg with a 300 dpi using ghostscript.
'ai' => [
'extension' => 'jpg',
'output_mime_type' => 'image/jpeg',
'program' => 'exec',
'command' => "gs -dUseArtBox -sDEVICE=jpeg -o %fn%.jpg -dJPEGQ=85 -r300x300 -f %fn%",
],
'eps' => [
'extension' => 'jpg',
'output_mime_type' => 'image/jpeg',
'program' => 'exec',
'command' => "gs -dUseArtBox -sDEVICE=jpeg -o %fn%.jpg -dJPEGQ=85 -r300x300 -f %fn%",
],
'pdf' => [
'extension' => 'jpg',
'output_mime_type' => 'image/jpeg',
'program' => 'exec',
'command' => "gs -dUseArtBox -sDEVICE=jpeg -o %fn%.jpg -dJPEGQ=85 -r300x300 -f %fn%",
],
// This will be process with darktable tool.
// Cannon raw files will be processed with darktable.
'cr2' => [
'extension' => 'jpg',
'output_mime_type' => 'image/jpeg',
'program' => 'darktable',
'command' => 'darktable-cli %fn% %fn%.jpg && rm %fn% && mv %fn%.jpg %fn%',
'program' => 'exec',
'command' => 'darktable-cli %fn% %fn%.jpg',
],
// This will be process with ffmpeg tool.
// mp4 video files will be processed with ffmpeg.
'mp4' => [
'extension' => 'jpg',
// 'input_mime_type' => 'video/mp4', // will be necessary in future
'output_mime_type' => 'image/jpeg',
'program' => 'ffmpeg',
'program' => 'exec',
// If the video doesn't have an embedded thumbnail then get a screenshot 5s in
// ffmpeg -ss 00:00:05 -i file_example_MP4_480_1_5MG.mp4 -vframes 1 -q:v 2 output.jpg // WORKS !!!!!!!
'command' => 'ffmpeg -ss 00:00:05 -i %fn% -vframes 1 -q:v 2 %fn%.jpg && rm %fn% && mv %fn%.jpg %fn%',
'command' => 'ffmpeg -ss 00:00:05 -i %fn% -vframes 1 -q:v 2 %fn%.jpg',
],
// https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format
......@@ -80,7 +79,6 @@ function auc_init() {
'program' => 'fast-rename', // Not real program - just key for switch.
'command' => 'fast-rename %fn% %fn%.jpg', // Not real command - only for log.
],
);
if (!empty($_FILES['file']['name'])
......@@ -130,9 +128,11 @@ function auc_init() {
/**
* Implements hook_file_validate().
*/
function auc_file_validate($file): array
{
function auc_file_validate($file): array {
module_load_include('inc', 'auc', 'auc.under_hood');
$errors = [];
// Make this configurable in the future.
$mime_types_being_tested = [
'image/jpeg',
'image/gif',
......
......@@ -31,26 +31,55 @@ const AUC_VIDEO_FORMATS = [
* @param $path_parts
* @param &$imagemagick_convert_checked
*
* @return false|void
* @return false|true
*/
function auc_ext_check($path_parts, &$imagemagick_convert_checked) {
if (empty($path_parts['extension'])) {
return FALSE;
}
// See if imagemagick supports this file extension.
// Move to admin section eventually.
if (empty($imagemagick_convert_checked[$path_parts['extension']])) {
$result = _imagemagick_convert_exec('-version', $output);
if (strpos($output, $path_parts['extension']) === FALSE) {
// Report Failure.
watchdog('auc', 'auto upload convert failed. convert binary does not support the @ext filetype.<br><pre>@result</pre><br>@output', array(
'@ext' => $path_parts['extension'],
'@result' => var_export($result, TRUE),
'@output' => $output,
));
return FALSE;
if (!empty($imagemagick_convert_checked[$path_parts['extension']])) {
return $imagemagick_convert_checked[$path_parts['extension']];
}
$result = _imagemagick_convert_exec('-version', $output);
$file_copies = array();
if (strpos($output, $path_parts['extension']) === FALSE) {
// Make a copy of the failed upload for further review.
if (!empty($_FILES['files']['name'])) {
foreach ($_FILES['files']['name'] as $field_name => $value) {
$file_name = $_FILES['files']['name'][$field_name];
$file_location = $_FILES['files']['tmp_name'][$field_name];
if (!is_uploaded_file($file_location)) {
continue;
}
$file_copies[] = file_unmanaged_copy($file_location, "public://thingy/{$file_name}");
}
}
else {
$imagemagick_convert_checked[$path_parts['extension']] = TRUE;
if (!empty($_FILES['file']['name'])) {
$file_name = $_FILES['file']['name'];
$file_location = $_FILES['file']['tmp_name'];
if (is_uploaded_file($file_location)) {
$file_copies[] = file_unmanaged_copy($file_location, "public://thingy/{$file_name}");
}
}
// Report Failure.
watchdog('auc', 'auto upload convert failed. convert binary does not support the @ext filetype.<br><pre>@result</pre><br>@output<br><pre>@file_copies</pre>', array(
'@ext' => $path_parts['extension'],
'@result' => var_export($result, TRUE),
'@output' => $output,
'@file_copies' => print_r($file_copies, TRUE),
));
$imagemagick_convert_checked[$path_parts['extension']] = FALSE;
}
else {
$imagemagick_convert_checked[$path_parts['extension']] = TRUE;
}
return $imagemagick_convert_checked[$path_parts['extension']];
}
/**
......@@ -59,7 +88,7 @@ function auc_ext_check($path_parts, &$imagemagick_convert_checked) {
* @param $command
* Command with file name, options etc.
* @param $program
* Which program to run for image editing, imagemagick or darktable.
* Which program to run: imagemagick or exec (darktable, ffmpeg, ghostscript).
*
* @return bool
*/
......@@ -71,13 +100,12 @@ function auc_convert_extension($command, $program): bool {
case 'imagemagick':
$result = _imagemagick_convert_exec($command, $output, $error);
break;
case 'darktable';
case 'ffmpeg';
// ffmpeg and darktable require extension for output file!
case 'exec';
// ffmpeg, darktable, ghostscript require extension for output file!
// It is impossible to convert into the same tmp file in $_FILES
// So we are creating new file with explicit extension and then replace
// original uploading file with it.
$result = auc_get_jpg_from_raw($command, $output, $error);
$result = auc_get_jpg_from_exec($command, $output, $error);
break;
case 'fast-rename':
$result = TRUE; // Renaming will be in any way in auc_process_wrapper().
......@@ -218,7 +246,7 @@ function auc_is_image_correct(stdClass $file): bool {
}
if ($imagemagick_fix) {
$message = 'This image was broken. imagemagick convert was able to fix it. Filename: %filename, filepath: %filepath, channels: %channels, bits: %bits. <br><pre>@file</pre> <br><pre>@post</pre> <br><pre>@files</pre> <br><pre>@phpinput</pre> <br><pre>@server</pre>';
watchdog('auc', $message, $placeholders);
watchdog('auc', $message, $placeholders, WATCHDOG_INFO);
}
// Return status.
......@@ -238,10 +266,10 @@ function auc_is_image_correct(stdClass $file): bool {
* @return bool
* Plus variables $output and $error are changing by reference.
*/
function auc_get_jpg_from_raw($command, &$output = NULL, &$error = NULL): bool {
function auc_get_jpg_from_exec($command, &$output = NULL, &$error = NULL): bool {
$is_success = FALSE;
$result = exec($command, $output, $error);
$result = exec("{$command}", $output, $error);
if ($result !== FALSE && $error == 0) {
$is_success = TRUE;
......@@ -295,28 +323,29 @@ function auc_get_field_allowed_extensions(string $field_name): array {
function auc_process_wrapper($conversion_lut, $path_parts, string $field_name = '') {
// Build command for external program.
// todo use goto construction for resizing received new jpg to 3000 px during this one request?
$tmp_name = !empty($field_name) ? $_FILES['files']['tmp_name'][$field_name] : $_FILES['file']['tmp_name'];
$input_file_extension = $path_parts['extension'];
$output_file_extension = $conversion_lut[$input_file_extension]['extension'];
$program = $conversion_lut[$input_file_extension]['program'];
$command = str_replace(
'%fn%',
escapeshellarg($tmp_name),
$conversion_lut[$input_file_extension]['command']
);
$command = $conversion_lut[$input_file_extension]['command'];
// Add in file rename if not using imagemagick
if ($program !== 'imagemagick') {
$command = "{$command} && rm %fn% && mv %fn%.jpg %fn%";
}
// Replace %fn% token with the actual filename.
$command = str_replace('%fn%', escapeshellarg($tmp_name), $command);
// See if imagemagick supports this file extension.
// Move to admin section eventually.
$imagemagick_convert_checked = array();
if ($program == 'imagemagick' && !auc_ext_check($path_parts, $imagemagick_convert_checked)) {
if ($program === 'imagemagick' && !auc_ext_check($path_parts, $imagemagick_convert_checked)) {
return;
}
// Check that field allows images but not video - otherwise fast return.
if ($program == 'ffmpeg') {
if ($input_file_extension === 'mp4') {
$allowed_extensions = auc_get_field_allowed_extensions($field_name);
if (
!is_array($allowed_extensions)
......@@ -348,7 +377,7 @@ function auc_process_wrapper($conversion_lut, $path_parts, string $field_name =
$file_name_ref = "{$path_parts['filename']}.{$output_file_extension}";
// Update 'type' when it is necessary.
if ($program == 'ffmpeg' || $program == 'darktable') {
if (!empty($conversion_lut[$input_file_extension]['output_mime_type'])) {
$file_type_ref = $conversion_lut[$input_file_extension]['output_mime_type'];
}
......@@ -385,8 +414,8 @@ function auc_get_mime_type(string $file_path) {
if (
$type === FALSE
|| $type == 'application/octet-stream'
|| $type == 'text/plain')
|| $type === 'application/octet-stream'
|| $type === 'text/plain')
{
$second_try = exec('file -b --mime-type ' . escapeshellarg($file_path), $output, $returned_code);
if ($returned_code === 0 && $second_try) {
......@@ -413,10 +442,10 @@ function auc_compare_extension_and_mime(string $file_path, string $original_exte
$type = auc_get_mime_type($file_path);
if (
$type != FALSE
!empty($type)
&& is_string($type)
&& isset($conversion_lut[$type])
&& $original_extension == $conversion_lut[$type]['original_extension'])
&& $original_extension === $conversion_lut[$type]['original_extension'])
{
$is_match = TRUE;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment