  class _CompressedSerializer(Serializer):
      """ A compressed pickle serializer for Faceswap """
      def __init__(self):
          super().__init__()
          self._file_extension = "fsc"
          self._child = get_serializer("pickle")
  
      def _marshal(self, data):
          """ Pickle and compress data """
          data = self._child._marshal(data)  # pylint: disable=protected-access
 
</s> remove     @staticmethod
    def get_serializer(filename):
        """ Set the serializer to be used for loading and
            saving alignments

            If a filename with a valid extension is passed in
            this will be used as the serializer, otherwise the
            compressed pickle will be used """
        logger.debug("Getting serializer: (filename: '%s')", filename)
        extension = os.path.splitext(filename)[1]
        if extension in (".json", ".p", ".yaml", ".yml"):
            logger.debug("Serializer set from filename extension: '%s'", extension)
            retval = get_serializer_from_filename(filename)
        else:
            logger.debug("Returning default Pickle serializer")
            retval = get_serializer("compressed")
        logger.verbose("Using '%s' serializer for alignments", retval.file_extension)
        return retval

 </s> add  </s> remove     def __init__(self, alignments_file, destination_format):
        logger.debug("Initializing %s: (alignments file: '%s', destination_format: '%s')",
                     self.__class__.__name__, alignments_file, destination_format)
 </s> add     def __init__(self, alignments_file):
        logger.debug("Initializing %s: (alignments file: '%s')",
                     self.__class__.__name__, alignments_file) </s> remove     @staticmethod
    def get_original_rotation_matrix(dimensions, angle):
        """ Calculate original rotation matrix and invert """
        logger.trace("Getting original rotation matrix: (dimensions: %s, angle: %s)",
                     dimensions, angle)
        height, width = dimensions
        center = (width/2, height/2)
        r_mat = cv2.getRotationMatrix2D(  # pylint: disable=no-member
            center, -1.0 * angle, 1.)

        abs_cos = abs(r_mat[0, 0])
        abs_sin = abs(r_mat[0, 1])
        rotated_width = int(height*abs_sin + width*abs_cos)
        rotated_height = int(height*abs_cos + width*abs_sin)
        r_mat[0, 2] += rotated_width/2 - center[0]
        r_mat[1, 2] += rotated_height/2 - center[1]
        logger.trace("Returning rotation matrix: %s", r_mat)
        return r_mat

    # <Face Hashes> #
    # The old index based method of face matching is problematic.
    # The SHA1 Hash of the extracted face is now stored in the alignments file.
    # This has it's own issues, but they are far reduced from the index/filename method
    # This can eventually be removed
    def get_legacy_no_hashes(self):
        """ Get alignments without face hashes """
        logger.debug("Getting alignments without face hashes")
        keys = list()
        for key, val in self.data.items():
            for alignment in val:
                if "hash" not in alignment.keys():
                    keys.append(key)
                    break
        logger.debug("Got alignments without face hashes: %s", len(keys))
        return keys

    def add_face_hashes(self, frame_name, hashes):
        """ Backward compatability fix. Add face hash to alignments """
        logger.trace("Adding face hash: (frame: '%s', hashes: %s)", frame_name, hashes)
        faces = self.get_faces_in_frame(frame_name)
        count_match = len(faces) - len(hashes)
        if count_match != 0:
            msg = "more" if count_match > 0 else "fewer"
            logger.warning("There are %s %s face(s) in the alignments file than exist in the "
                           "faces folder. Check your sources for frame '%s'.",
                           abs(count_match), msg, frame_name)
        for idx, i_hash in hashes.items():
            faces[idx]["hash"] = i_hash
 </s> add     # <File Format> #
    # Serializer is now a compressed pickle .fsa format. This used to be any number of serializers
    def update_file_format(self, folder, filename):
        """ Convert old style alignments format to new style format """
        logger.info("Reformatting legacy alignments file...")
        old_location = os.path.join(str(folder), filename)
        new_location = "{}.{}".format(os.path.splitext(old_location)[0],
                                      self.serializer.file_extension)
        logger.info("Old location: '%s', New location: '%s'", old_location, new_location)

        load_serializer = get_serializer_from_filename(old_location)
        data = load_serializer.load(old_location)
        self.serializer.save(new_location, data)
        return os.path.basename(new_location) </s> remove             filename, extension = os.path.splitext(filename)
            serializer = extension[1:]
            alignments = Alignments(
                path,
                filename=filename,
                serializer=serializer)
 </s> add             alignments = Alignments(path, filename=filename) </s> remove             raise ValueError("Error: Alignments file not found at "
                             "{}".format(self.file))
 </s> add             raise FaceswapError("Error: Alignments file not found at "
                                "{}".format(self.file))
        self._file_extension = "fsa"
  class _CompressedSerializer(Serializer):
      """ A compressed pickle serializer for Faceswap """
      def __init__(self):
          super().__init__()
        self._file_extension = "fsa"
          self._child = get_serializer("pickle")
  
      def _marshal(self, data):
          """ Pickle and compress data """
          data = self._child._marshal(data)  # pylint: disable=protected-access
keep keep keep keep replace keep keep keep keep keep
 Legacy alignments update

- Remove legacy update hashes
- Remove legacy job from alignment-tools
- Remove legacy landmark rotation
- Add rotate face method to plugins/extract/detect
- Update travis test for new alignments extension
- Alignments format to .fsa
- Remove serializer option from alignments-tool
- Auto update legacy format alignment files to new format 
lib/serializer.py