Author image Clipland
and 1 contributors


Image::Animated::JPEG - Library and scripts to create, play and modify Animated JPEG files


   use Image::MetaData::JPEG;
   use Image::Animated::JPEG;

   ## load a JPEG file
   my $file = new Image::MetaData::JPEG($input_file);

   my $ref = Image::Animated::JPEG::encode_ajpeg_marker({
      delay  => 100,  # delay 100ms per frame
      repeat => 0,    # repeat forever

   ## create a new APP0 segment/"tag"
   my $ani_seg = Image::MetaData::JPEG::Segment->new(
      \$ref,     # ref to Animated JPEG conform APP0 payload
      'NOPARSE', # tell Image::MetaData to not parse the segment (as it doesn't understand it, yet)

   ## insert newly created segment, and write file


This module provides functions to handle Animated JPEG files (AJPEGs), which are similar to Motion-JPEG files, as they are just a concatenation of JPEGs.

The proposed Animated JPEG standard utilises JPEG/JFIF's APP0 application extension segments to store playback settings, e.g. frame-rate (delay), loop behaviour (repeat), etc., JFIF compliant as an additional APP0 marker. This way, MJPEG files become a self-contained animation file similar to animated GIF files.

The routines found in this module are able to index frames within an AJPEG file, to process single frames in order to extract APP0 markers, and it provides functions to encode and read segments in Animated JPEG's proposed segment data format, version 0.

Also, this distribution comes bundled with five Animated JPEG utility scripts which employ this module's routines to create, transform and play AJPEG files:

  • makeajpeg - script to create Animated JPEG files on command-line.

  • playajpeg - a WxPerl-based Animated JPEG player GUI application.

  • gif2ajpeg - utilizes ImageMagick's convert and makeani to convert animated gif files to Animated JPEG files.

  • ajpeg2gif - uses makeajpeg to assemble and animated GIF from an animated JPEG.

  • ajpegtran - lossless cropping of an entire animated JPEG animation by executing jpegtran on every separate frame.

If you are interested in details of the proposed AJPEG format, the Why and How, then read the README and SPECIFICATIONS files bundled with this distribution.

Also, the README file provides further information on how to set MIME-Type, etc. on a *nix system so .ajpeg files get associated with playajpeg.


index($filehandle, $args)

Assumes a file is a concatenation of JPEG files, as known from MJPEG files and as required for AJPEG files. Operates on the whole file. Scans such a file for chunk/frame boundaries and builds an index of seek-offsets within the file.

Returns a reference to an array-of-hashes, each hash providing byte offsets (boundaries) for each frame within the ajpeg file.

process($ref or $file)

This function operates on a chunk of a whole file (the single frame) or on a singular file. It scans a JPEG/JFIF file/stream for APP0 segments.

Expects either a reference to a scalar holding a JPEG image (an in-memory JPEG stream), or a scalar with a filename/path of a JPEG file. Relies on IO::String for in-memory streams.

Dies on error.

Returns a hash-of-hashes, with marker names (JFIF, AJPEG, ...) as keys, pointing to marker related information, for example:

      AJPEG => {
         type   => 'APP0', # the only type of marker this function is looking for
         offset => ,       # position in file/stream, zero-based
         length => ,       # of the segment, as defined in JFIF "everything except leading \xFFF0"
         data_offset =>    # position where AJPEG marker payload begins (after application extension zero-terminator)
         data_length =>    # length of AJPEG data, everything from AJPEG version byte until end of segment
      JFIF => {

Expects a hashref with animation properties:

      delay      => # numeric value
      repeat     => # numeric value
      parse_next => # numeric value
      length     => # numeric value
      previous   => # numeric value
      x_offset   => # numeric value
      y_offset   => # numeric value
      dispose_op => # numeric value
      metadata   => {
         # hashref with arbitrary metadata key:value pairs

Dies on error.

Returns a scalar holding binary data (future segment's payload) on success.

Optionally, a second hashref holding arguments may be passed in:

        debug    => 1 # if set to true, print some info to stdout

Parses marker data according to AJPEG specs.

Expects a scalar holding binary data from an JPEG/JFIF APP0 marker, payload only. That means: without leading "\xFF\xE0" APP0 mark, and without the two bytes "chunk length" coming after the APP0 mark, and without the AJPEG application extension identifier and without the binary-zero terminator trailing after it. For an AJPEG segment, this means everything beginning with the version byte, including the version byte itself, until the end of the segment.

Dies on error.

Returns a hashref with parameters found in the marker data.

Optionally, a second hashref holding arguments may be passed in:

        debug    => 1 # if set to true, print some info to stdout


This module is alpha quality code. Don't use it to process important data unless you know what you're doing.

The proposed Animated JPEG format specs are at version 0 (experimental, Request for Comments). The specifications and this module's interface may change.




Image::MetaData::JPEG, Image::Info

This module and the Animated JPEG specifications currently reside on github.

Specifications are also bundled with this distribution.


Clipland GmbH


Copyright 2013-2019 Clipland GmbH. All rights reserved.

This library is free software, dual-licensed under GPLv3/AL2. You can redistribute it and/or modify it under the same terms as Perl itself.

JPEG marker parsing routines are mostly based on functions found in Image::Info, copyright 1999-2004 Gisle Aas, Tels 2006 - 2008, Slaven Rezic 2008 - 2013, et al. Respective portions are marked in the source.