<commit_before>﻿using System;
using FFImageLoading.Decoders;
using Android.Graphics;
using FFImageLoading.Work;
using System.IO;
using System.Threading.Tasks;
using FFImageLoading.Drawables;
using FFImageLoading.Cache;
using FFImageLoading.Helpers;
using FFImageLoading.Config;
using FFImageLoading.Extensions;

namespace FFImageLoading.Decoders
{
    public class BaseDecoder : IDecoder<Bitmap>
    {
        public async Task<IDecodedImage<Bitmap>> DecodeAsync(Stream imageData, string path, ImageSource source, ImageInformation imageInformation, TaskParameter parameters)
        {
            BitmapFactory.Options options = null;
            Bitmap bitmap = null;

            if (imageData == null)
                throw new ArgumentNullException(nameof(imageData));

            if (options == null)
            {
                // First decode with inJustDecodeBounds=true to check dimensions
                options = new BitmapFactory.Options
                {
                    InJustDecodeBounds = true,
                };
                await BitmapFactory.DecodeStreamAsync(imageData, null, options).ConfigureAwait(false);
            }

            options.InPurgeable = true;
            options.InJustDecodeBounds = false;
            options.InDither = true;

            imageInformation.SetOriginalSize(options.OutWidth, options.OutHeight);
            imageInformation.SetCurrentSize(options.OutWidth, options.OutHeight);

            if (!Configuration.BitmapOptimizations || (parameters.BitmapOptimizationsEnabled.HasValue && !parameters.BitmapOptimizationsEnabled.Value))
            {
                // Same quality but no transparency channel. This allows to save 50% of memory: 1 pixel=2bytes instead of 4.
                options.InPreferredConfig = Bitmap.Config.Rgb565;
                options.InPreferQualityOverSpeed = false;
            }

            // CHECK IF BITMAP IS EXIF ROTATED
            int exifRotation = 0;
            try
            {
                exifRotation = imageData.GetExifRotationDegrees();
            }
            catch (Exception ex)
            {
                Logger.Error("Reading EXIF orientation failed", ex);
            }

            if (imageData.Position != 0)
                imageData.Position = 0;

            // DOWNSAMPLE
            if (parameters.DownSampleSize != null && (parameters.DownSampleSize.Item1 > 0 || parameters.DownSampleSize.Item2 > 0))
            {
                // Calculate inSampleSize
                int downsampleWidth = parameters.DownSampleSize.Item1;
                int downsampleHeight = parameters.DownSampleSize.Item2;

                if (parameters.DownSampleUseDipUnits)
                {
                    downsampleWidth = downsampleWidth.DpToPixels();
                    downsampleHeight = downsampleHeight.DpToPixels();<commit_msg>Android - don't check EXIF for some source types<commit_after>﻿using System;
using FFImageLoading.Decoders;
using Android.Graphics;
using FFImageLoading.Work;
using System.IO;
using System.Threading.Tasks;
using FFImageLoading.Drawables;
using FFImageLoading.Cache;
using FFImageLoading.Helpers;
using FFImageLoading.Config;
using FFImageLoading.Extensions;

namespace FFImageLoading.Decoders
{
    public class BaseDecoder : IDecoder<Bitmap>
    {
        public async Task<IDecodedImage<Bitmap>> DecodeAsync(Stream imageData, string path, ImageSource source, ImageInformation imageInformation, TaskParameter parameters)
        {
            BitmapFactory.Options options = null;
            Bitmap bitmap = null;

            if (imageData == null)
                throw new ArgumentNullException(nameof(imageData));

            if (options == null)
            {
                // First decode with inJustDecodeBounds=true to check dimensions
                options = new BitmapFactory.Options
                {
                    InJustDecodeBounds = true,
                };
                await BitmapFactory.DecodeStreamAsync(imageData, null, options).ConfigureAwait(false);
            }

            options.InPurgeable = true;
            options.InJustDecodeBounds = false;
            options.InDither = true;

            imageInformation.SetOriginalSize(options.OutWidth, options.OutHeight);
            imageInformation.SetCurrentSize(options.OutWidth, options.OutHeight);

            if (!Configuration.BitmapOptimizations || (parameters.BitmapOptimizationsEnabled.HasValue && !parameters.BitmapOptimizationsEnabled.Value))
            {
                // Same quality but no transparency channel. This allows to save 50% of memory: 1 pixel=2bytes instead of 4.
                options.InPreferredConfig = Bitmap.Config.Rgb565;
                options.InPreferQualityOverSpeed = false;
            }

            // CHECK IF BITMAP IS EXIF ROTATED
            int exifRotation = 0;

            if ((source == ImageSource.Filepath || source == ImageSource.Stream || source == ImageSource.Url)
                && imageInformation.Type != ImageInformation.ImageType.SVG)
            {
                try
                {
                    exifRotation = imageData.GetExifRotationDegrees();
                }
                catch (Exception ex)
                {
                    Logger.Error("Reading EXIF orientation failed", ex);
                }
            }

            if (imageData.Position != 0)
                imageData.Position = 0;

            // DOWNSAMPLE
            if (parameters.DownSampleSize != null && (parameters.DownSampleSize.Item1 > 0 || parameters.DownSampleSize.Item2 > 0))
            {
                // Calculate inSampleSize
                int downsampleWidth = parameters.DownSampleSize.Item1;
                int downsampleHeight = parameters.DownSampleSize.Item2;

                if (parameters.DownSampleUseDipUnits)
                {
                    downsampleWidth = downsampleWidth.DpToPixels();
                    downsampleHeight = downsampleHeight.DpToPixels();
{'fraction_non_alphanumeric': 0.07495003331112592, 'fraction_numerical': 0.005662891405729514, 'mean_word_length': 2.000999500249875, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7753', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1407, 'n_words': 325}