<commit_before>//
//  UIImage+SwiftyGif.swift
//

import ImageIO
import UIKit
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
    switch (lhs, rhs) {
    case let (l?, r?):
        return l < r
    case (nil, _?):
        return true
    default:
        return false
    }
}

fileprivate func <= <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
    switch (lhs, rhs) {
    case let (l?, r?):
        return l <= r
    default:
        return !(rhs < lhs)
    }
}


let _imageSourceKey = malloc(4)
let _displayRefreshFactorKey = malloc(4)
let _imageCountKey = malloc(4)
let _displayOrderKey = malloc(4)
let _imageSizeKey = malloc(4)
let _imageDataKey = malloc(4)

let defaultLevelOfIntegrity: Float = 0.8


fileprivate enum GifParseError:Error {
    case noProperties
    case noGifDictionary
    case noTimingInfo
}


public extension UIImage {
    
    // MARK: Inits
    
    /**
     Convenience initializer. Creates a gif with its backing data. Defaulted level of integrity.
     - Parameter gifData: The actual gif data
     */
    public convenience init(gifData:Data) {
        self.init()
        setGifFromData(gifData,levelOfIntegrity: defaultLevelOfIntegrity)
    }
    
    /**
     Convenience initializer. Creates a gif with its backing data.
     - Parameter gifData: The actual gif data
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public convenience init(gifData:Data, levelOfIntegrity:Float) {
        self.init()
        setGifFromData(gifData,levelOfIntegrity: levelOfIntegrity)
    }
    
    /**
     Convenience initializer. Creates a gif with its backing data. Defaulted level of integrity.
     - Parameter gifName: Filename
     */
    public convenience init(gifName: String) {
        self.init()
        setGif(gifName, levelOfIntegrity: defaultLevelOfIntegrity)
    }
    
    /**
     Convenience initializer. Creates a gif with its backing data.
     - Parameter gifName: Filename
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public convenience init(gifName: String, levelOfIntegrity: Float) {
        self.init()
        setGif(gifName, levelOfIntegrity: levelOfIntegrity)
    }
    
    /**
     Set backing data for this gif. Overwrites any existing data.
     - Parameter data: The actual gif data
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public func setGifFromData(_ data:Data,levelOfIntegrity:Float) {
        guard let imageSource = CGImageSourceCreateWithData(data as CFData, nil) else { return }
        self.imageSource = imageSource
        self.imageData = data

        do {
            calculateFrameDelay(try delayTimes(imageSource), levelOfIntegrity: levelOfIntegrity)
        } catch {
            print("Could not determine delay times for GIF.")
            return
        }
        calculateFrameSize()
    }
    
    /**
     Set backing data for this gif. Overwrites any existing data.
     - Parameter name: Filename
     */
    public func setGif(_ name: String) {
        setGif(name, levelOfIntegrity: defaultLevelOfIntegrity)
    }
    
    /**
     Check the number of frame for this gif
     - Return number of frames
     */
    public func framesCount() -> Int{
        if let orders = self.displayOrder{
            return orders.count
        }
        return 0
    }
    
    /**
     Set backing data for this gif. Overwrites any existing data.
     - Parameter name: Filename
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public func setGif(_ name: String, levelOfIntegrity: Float) {
        if let url = Bundle.main.url(forResource: name,
                                     withExtension: name.getPathExtension() == "gif" ? "" : "gif") {
            if let data = try? Data(contentsOf: url) {
                setGifFromData(data,levelOfIntegrity: levelOfIntegrity)
            } else {
                print("Error : Invalid GIF data for \(name).gif")
            }
        } else {
            print("Error : Gif file \(name).gif not found")
        }
    }
    
    public func clear() {
        imageData = nil
        imageSource = nil
        displayOrder = nil
        imageCount = nil
        imageSize = nil
        displayRefreshFactor = nil
    }
    
    // MARK: Logic

    fileprivate func convertToDelay(_ pointer:UnsafeRawPointer?) -> Float? {
        if pointer == nil {
            return nil
        }
        let value = unsafeBitCast(pointer, to:AnyObject.self)
        return value.floatValue
    }

    /**
     Get delay times for each frames
     - Parameter imageSource: reference to the gif image source
     - Returns array of delays
     */
    fileprivate func delayTimes(_ imageSource:CGImageSource) throws ->[Float] {
        
        let imageCount = CGImageSourceGetCount(imageSource)
        var imageProperties = [CFDictionary]()
        for i in 0..<imageCount{
            if let dict = CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil) {
                imageProperties.append(dict)
            } else {
                throw GifParseError.noProperties
            }
        }<commit_msg>Throw an error during parsing if an image source has no images.<commit_after>//
//  UIImage+SwiftyGif.swift
//

import ImageIO
import UIKit
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
    switch (lhs, rhs) {
    case let (l?, r?):
        return l < r
    case (nil, _?):
        return true
    default:
        return false
    }
}

fileprivate func <= <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
    switch (lhs, rhs) {
    case let (l?, r?):
        return l <= r
    default:
        return !(rhs < lhs)
    }
}


let _imageSourceKey = malloc(4)
let _displayRefreshFactorKey = malloc(4)
let _imageCountKey = malloc(4)
let _displayOrderKey = malloc(4)
let _imageSizeKey = malloc(4)
let _imageDataKey = malloc(4)

let defaultLevelOfIntegrity: Float = 0.8


fileprivate enum GifParseError:Error {
    case noImages
    case noProperties
    case noGifDictionary
    case noTimingInfo
}


public extension UIImage {
    
    // MARK: Inits
    
    /**
     Convenience initializer. Creates a gif with its backing data. Defaulted level of integrity.
     - Parameter gifData: The actual gif data
     */
    public convenience init(gifData:Data) {
        self.init()
        setGifFromData(gifData,levelOfIntegrity: defaultLevelOfIntegrity)
    }
    
    /**
     Convenience initializer. Creates a gif with its backing data.
     - Parameter gifData: The actual gif data
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public convenience init(gifData:Data, levelOfIntegrity:Float) {
        self.init()
        setGifFromData(gifData,levelOfIntegrity: levelOfIntegrity)
    }
    
    /**
     Convenience initializer. Creates a gif with its backing data. Defaulted level of integrity.
     - Parameter gifName: Filename
     */
    public convenience init(gifName: String) {
        self.init()
        setGif(gifName, levelOfIntegrity: defaultLevelOfIntegrity)
    }
    
    /**
     Convenience initializer. Creates a gif with its backing data.
     - Parameter gifName: Filename
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public convenience init(gifName: String, levelOfIntegrity: Float) {
        self.init()
        setGif(gifName, levelOfIntegrity: levelOfIntegrity)
    }
    
    /**
     Set backing data for this gif. Overwrites any existing data.
     - Parameter data: The actual gif data
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public func setGifFromData(_ data:Data,levelOfIntegrity:Float) {
        guard let imageSource = CGImageSourceCreateWithData(data as CFData, nil) else { return }
        self.imageSource = imageSource
        self.imageData = data

        do {
            calculateFrameDelay(try delayTimes(imageSource), levelOfIntegrity: levelOfIntegrity)
        } catch {
            print("Could not determine delay times for GIF.")
            return
        }
        calculateFrameSize()
    }
    
    /**
     Set backing data for this gif. Overwrites any existing data.
     - Parameter name: Filename
     */
    public func setGif(_ name: String) {
        setGif(name, levelOfIntegrity: defaultLevelOfIntegrity)
    }
    
    /**
     Check the number of frame for this gif
     - Return number of frames
     */
    public func framesCount() -> Int{
        if let orders = self.displayOrder{
            return orders.count
        }
        return 0
    }
    
    /**
     Set backing data for this gif. Overwrites any existing data.
     - Parameter name: Filename
     - Parameter levelOfIntegrity: 0 to 1, 1 meaning no frame skipping
     */
    public func setGif(_ name: String, levelOfIntegrity: Float) {
        if let url = Bundle.main.url(forResource: name,
                                     withExtension: name.getPathExtension() == "gif" ? "" : "gif") {
            if let data = try? Data(contentsOf: url) {
                setGifFromData(data,levelOfIntegrity: levelOfIntegrity)
            } else {
                print("Error : Invalid GIF data for \(name).gif")
            }
        } else {
            print("Error : Gif file \(name).gif not found")
        }
    }
    
    public func clear() {
        imageData = nil
        imageSource = nil
        displayOrder = nil
        imageCount = nil
        imageSize = nil
        displayRefreshFactor = nil
    }
    
    // MARK: Logic

    fileprivate func convertToDelay(_ pointer:UnsafeRawPointer?) -> Float? {
        if pointer == nil {
            return nil
        }
        let value = unsafeBitCast(pointer, to:AnyObject.self)
        return value.floatValue
    }

    /**
     Get delay times for each frames
     - Parameter imageSource: reference to the gif image source
     - Returns array of delays
     */
    fileprivate func delayTimes(_ imageSource:CGImageSource) throws ->[Float] {
        
        let imageCount = CGImageSourceGetCount(imageSource)
        guard imageCount > 0 else {
            throw GifParseError.noImages
        }
        var imageProperties = [CFDictionary]()
        for i in 0..<imageCount{
            if let dict = CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil) {
                imageProperties.append(dict)
            } else {
                throw GifParseError.noProperties
            }
        }
{'fraction_non_alphanumeric': 0.0829760884062113, 'fraction_numerical': 0.004286939125464418, 'mean_word_length': 2.1346670647954613, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6417319', 'n_tokens_mistral': 3043, 'n_tokens_neox': 2951, 'n_words': 905}