Rockbox Technical Forums

Third Party => Other Utilities => Topic started by: cereal_killer on August 24, 2018, 09:31:08 AM

Title: Shell script for converting progressive JPEGs to baseline
Post by: cereal_killer on August 24, 2018, 09:31:08 AM
I found this shell script to convert progressive JPEG files to baseline: https://www.codeproject.com/Articles/438021/Shell-script-for-converting-progressive-JPEGs-to-b (https://www.codeproject.com/Articles/438021/Shell-script-for-converting-progressive-JPEGs-to-b). This is much quicker than batch converting with irfanview. But unfortunately it won't work with file/folder names with spaces.

Code: [Select]
for img in `find . -name "*" | egrep *\.jpe?g$`
do
  idout=`identify -verbose $img | grep -i interlace | grep -i none$`

  if [[ -z $idout ]]
  then
    echo "-------------------------"
    echo "$img is progressive"
    echo "....making copy of original with .prog extension"
    /bin/cp -f $img $img.prog
    echo "....converting to baseline"
    convert $img -interlace none $img
    echo "....done!"
  #else
    #echo "$img is non-progressive"
  fi
done

I already tried to insert " in line 3, but it still doesn't work. My scripting knowledge is close to none. The Author hasn't responded to my inquiry yet. Does anyone have a fix for this? I think the part with copying the file with a new file extension is unnecessary. This surely would be a helpful tool and is worth to be added to https://www.rockbox.org/wiki/AlbumArt (https://www.rockbox.org/wiki/AlbumArt).
I appreciate any help.
Title: Re: Shell script for converting progressive JPEGs to baseline
Post by: Bilgus on August 24, 2018, 11:10:12 AM
I'm not the most versed with shell scripts but I believe the problem is with what the shell considers a valid field separator
by default I think it is SPACE|TAB|NEWLINE so it needs to be set to just newline


Code: [Select]
IFS_ORIG=$IFS #save original IFS will restore at end
set -f #Disable filename expansion (globbing).
IFS=$'\n'
for img in `find . -name "*" | egrep *\.jpe?g$`
do
  idout=`identify -verbose $img | grep -i interlace | grep -i none$`

  if [[ -z $idout ]]
  then
    echo "-------------------------"
    echo "$img is progressive"
    echo "....making copy of original with .prog extension"
    /bin/cp -f $img $img.prog
    echo "....converting to baseline"
    convert $img -interlace none $img
    echo "....done!"
  #else
    #echo "$img is non-progressive"
  fi
done
set +f
IFS=$IFS_ORIG
Title: Re: Shell script for converting progressive JPEGs to baseline
Post by: cereal_killer on August 24, 2018, 01:35:53 PM
Thank you so much Bilgus, now it works perfectly. I'll add this to the wiki, maybe someone else will find this usefull.
Title: Re: Shell script for converting progressive JPEGs to baseline
Post by: gevaerts on August 24, 2018, 04:17:08 PM
Just for the record, newlines are perfectly valid in filenames, so that script is still breakable :)
Title: Re: Shell script for converting progressive JPEGs to baseline
Post by: cereal_killer on September 03, 2018, 11:37:27 AM
Just for the record, newlines are perfectly valid in filenames, so that script is still breakable :)

I hope that this isn't the case very often. If there are newlines in filenames, I hope that the user has the knowledge to adjust this script. It is working fine for me and hopefully for many others, so I'll put it on the wiki.

Thank you Bilgus for the help.
Title: Re: Shell script for converting progressive JPEGs to baseline
Post by: rockbox_dev123 on April 13, 2019, 11:48:27 AM
Just for the record, newlines are perfectly valid in filenames, so that script is still breakable :)

See the canonical response for issues with iterating the output of find here:
https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29

Quote
If you're using bash, then you have two additional options. One is to use GNU or BSD find's -print0 option, together with bash's read -d '' option and a ProcessSubstitution:
Code: [Select]
while IFS= read -r -d '' file; do
  some command "$file"
done < <(find . -type f -name '*.mp3' -print0)

Are you using bash as your shell? If so I would drop the backticks because of this: http://mywiki.wooledge.org/BashFAQ/082

I would rewrite the script to make it a little more solid like this:
Code: [Select]
#!/usr/bin/env bash
 
function process_jpeg()
{
img="$1"
idout="$(identify -verbose "$img" | grep -i interlace | grep -i none)"

if [[ -z "$idout" ]]
then
echo "-------------------------"
echo "$img is progressive"
echo "....making copy of original with .prog extension"
/bin/cp -f "$img" "$img.prog"
echo "....converting to baseline"
convert "$img" -interlace none "$img"
echo "....done!"
fi
}

command -v identify >/dev/null 2>&1 || { echo >&2 "identify is required, but not installed.  Aborting."; exit 1; };

while IFS= read -r -d '' file; do process_jpeg "$file"; done < <(find "$PWD" -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) -print0)

I also highly recommend using https://github.com/koalaman/shellcheck

Edit: Just realised this was from 2018... time to make coffee
Title: Re: Shell script for converting progressive JPEGs to baseline
Post by: cereal_killer on April 22, 2019, 02:48:46 PM
Thanks for the rewrite and the additional information and tools bobba_mosfet. I'll update the wiki.