<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use embedder_traits::resources::{self, Resource};
use immeta::load_from_buf;
use net_traits::image::base::{load_from_memory, Image, ImageMetadata, PixelFormat};
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageResponder};
use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, ImageState};
use net_traits::image_cache::{PendingImageId, UsePlaceholder};
use net_traits::{FetchMetadata, FetchResponseMsg, NetworkError};
use servo_url::ServoUrl;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
use std::io;
use std::mem;
use std::sync::{Arc, Mutex};
use std::thread;

///
/// TODO(gw): Remaining work on image cache:
///     * Make use of the prefetch support in various parts of the code.
///     * Profile time in GetImageIfAvailable - might be worth caching these
///       results per paint / layout thread.
///
/// MAYBE(Yoric):
///     * For faster lookups, it might be useful to store the LoadKey in the
///       DOM once we have performed a first load.

// ======================================================================
// Helper functions.
// ======================================================================

fn decode_bytes_sync(key: LoadKey, bytes: &[u8]) -> DecoderMsg {
    let image = load_from_memory(bytes);
    DecoderMsg {
        key: key,
        image: image,
    }
}

fn get_placeholder_image(
    webrender_api: &webrender_api::RenderApi,
    data: &[u8],
) -> io::Result<Arc<Image>> {
    let mut image = load_from_memory(&data).unwrap();
    set_webrender_image_key(webrender_api, &mut image);
    Ok(Arc::new(image))
}

fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut Image) {
    if image.id.is_some() {
        return;
    }
    let mut bytes = Vec::new();
    let is_opaque = match image.format {
        PixelFormat::BGRA8 => {
            bytes.extend_from_slice(&*image.bytes);
            pixels::rgba8_premultiply_inplace(bytes.as_mut_slice())
        },
        PixelFormat::RGB8 => {
            for bgr in image.bytes.chunks(3) {
                bytes.extend_from_slice(&[bgr[2], bgr[1], bgr[0], 0xff]);
            }

            true
        },
        PixelFormat::K8 | PixelFormat::KA8 => {
            panic!("Not support by webrender yet");<commit_msg>Optimise memory allocation in set_webrender_image_key<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use embedder_traits::resources::{self, Resource};
use immeta::load_from_buf;
use net_traits::image::base::{load_from_memory, Image, ImageMetadata, PixelFormat};
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageResponder};
use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, ImageState};
use net_traits::image_cache::{PendingImageId, UsePlaceholder};
use net_traits::{FetchMetadata, FetchResponseMsg, NetworkError};
use servo_url::ServoUrl;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
use std::io;
use std::mem;
use std::sync::{Arc, Mutex};
use std::thread;

///
/// TODO(gw): Remaining work on image cache:
///     * Make use of the prefetch support in various parts of the code.
///     * Profile time in GetImageIfAvailable - might be worth caching these
///       results per paint / layout thread.
///
/// MAYBE(Yoric):
///     * For faster lookups, it might be useful to store the LoadKey in the
///       DOM once we have performed a first load.

// ======================================================================
// Helper functions.
// ======================================================================

fn decode_bytes_sync(key: LoadKey, bytes: &[u8]) -> DecoderMsg {
    let image = load_from_memory(bytes);
    DecoderMsg {
        key: key,
        image: image,
    }
}

fn get_placeholder_image(
    webrender_api: &webrender_api::RenderApi,
    data: &[u8],
) -> io::Result<Arc<Image>> {
    let mut image = load_from_memory(&data).unwrap();
    set_webrender_image_key(webrender_api, &mut image);
    Ok(Arc::new(image))
}

fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut Image) {
    if image.id.is_some() {
        return;
    }
    let mut bytes = Vec::new();
    let is_opaque = match image.format {
        PixelFormat::BGRA8 => {
            bytes.extend_from_slice(&*image.bytes);
            pixels::rgba8_premultiply_inplace(bytes.as_mut_slice())
        },
        PixelFormat::RGB8 => {
            bytes.reserve(image.bytes.len() / 3 * 4);
            for bgr in image.bytes.chunks(3) {
                bytes.extend_from_slice(&[bgr[2], bgr[1], bgr[0], 0xff]);
            }

            true
        },
        PixelFormat::K8 | PixelFormat::KA8 => {
            panic!("Not support by webrender yet");
{'fraction_non_alphanumeric': 0.17970565453137102, 'fraction_numerical': 0.006584043377226956, 'mean_word_length': 3.6364452423698386, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, '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': '1182428', 'n_tokens_mistral': 1623, 'n_tokens_neox': 1555, 'n_words': 402}