text: from __future__ import absolute_import
  
  import subprocess
  import re
  
  from . import ConverterBase
  from ..conf.settings import IM_CONVERT_PATH, IM_IDENTIFY_PATH
  from ..exceptions import ConvertError, UnknownFileFormat, IdentifyError
  from ..literals import (TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE,
      TRANSFORMATION_ZOOM, DIMENSION_SEPARATOR, DEFAULT_PAGE_NUMBER,
      DEFAULT_FILE_FORMAT)
  
  CONVERTER_ERROR_STRING_NO_DECODER = u'no decode delegate for this image format'
  
  
  class ImageMagick(ConverterBase):
      def identify_file(self, input_filepath, arguments=None):
          command = []
          command.append(unicode(IM_IDENTIFY_PATH))
          if arguments:
              command.extend(arguments)
          command.append(unicode(input_filepath))
  
          proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
          return_code = proc.wait()
          if return_code != 0:
              raise IdentifyError(proc.stderr.readline())
          return proc.stdout.read()
  
      def convert_file(self, input_filepath, output_filepath, transformations=None, page=DEFAULT_PAGE_NUMBER, file_format=DEFAULT_FILE_FORMAT, **kwargs):
          arguments = []
          try:
              if transformations:
                  for transformation in transformations:
                      if transformation['transformation'] == TRANSFORMATION_RESIZE:
                          dimensions = []
                          dimensions.append(unicode(transformation['arguments']['width']))
                          if 'height' in transformation['arguments']:
                              dimensions.append(unicode(transformation['arguments']['height']))
                          arguments.append(u'-resize')
                          arguments.append(u'%s' % DIMENSION_SEPARATOR.join(dimensions))
  
                      elif transformation['transformation'] == TRANSFORMATION_ZOOM:
                          arguments.append(u'-resize')
                          arguments.append(u'%d%%' % transformation['arguments']['percent'])
  
                      elif transformation['transformation'] == TRANSFORMATION_ROTATE:
                          arguments.append(u'-rotate')
                          arguments.append(u'%s' % transformation['arguments']['degrees'])
          except:
              pass
  
          if file_format.lower() == u'jpeg' or file_format.lower() == u'jpg':
              arguments.append(u'-quality')
              arguments.append(u'85')
  
          # Imagemagick page number is 0 base
          input_arg = u'%s[%d]' % (input_filepath, page - 1)
  
          # Specify the file format next to the output filename
          output_filepath = u'%s:%s' % (file_format, output_filepath)
  
          command = []
          command.append(unicode(IM_CONVERT_PATH))
          command.append(unicode(input_arg))
          if arguments:
              command.extend(arguments)
          command.append(unicode(output_filepath))
          proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
          return_code = proc.wait()
          if return_code != 0:
              # Got an error from convert program
              error_line = proc.stderr.readline()
              if CONVERTER_ERROR_STRING_NO_DECODER in error_line:
                  # Try to determine from error message which class of error is it
                  raise UnknownFileFormat
              else:
                  raise ConvertError(error_line)
  
      def get_format_list(self):
          """
          Call ImageMagick to parse all of it's supported file formats, and
          return a list of the names and descriptions
          """
          format_regex = re.compile(' *([A-Z0-9]+)[*]? +([A-Z0-9]+) +([rw\-+]+) *(.*).*')
          formats = []
          command = []
          command.append(unicode(IM_CONVERT_PATH))
          command.append(u'-list')
          command.append(u'format')
          proc = subprocess.Popen(command, close_fds=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
          return_code = proc.wait()
          if return_code != 0:
              raise ConvertError(proc.stderr.readline())
  
          for line in proc.stdout.readlines():
              fields = format_regex.findall(line)
              if fields:
                  formats.append(fields[0][0])
  
          return formats
  
      def get_available_transformations(self):
          return [
              TRANSFORMATION_RESIZE, TRANSFORMATION_ROTATE,
              TRANSFORMATION_ZOOM
          ]
  
      def get_page_count(self, input_filepath):
          try:
              return len(self.identify_file(unicode(input_filepath)).splitlines())
          except IdentifyError:
              raise UnknownFileFormat
  