Path: blob/master/thirdparty/libwebp/src/dsp/lossless_enc_mips_dsp_r2.c
9913 views
// Copyright 2015 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Image transform methods for lossless encoder.10//11// Author(s): Djordje Pesut ([email protected])12// Jovan Zelincevic ([email protected])1314#include "src/dsp/dsp.h"1516#if defined(WEBP_USE_MIPS_DSP_R2)1718#include "src/dsp/lossless.h"1920static void SubtractGreenFromBlueAndRed_MIPSdspR2(uint32_t* argb_data,21int num_pixels) {22uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;23uint32_t* const p_loop1_end = argb_data + (num_pixels & ~3);24uint32_t* const p_loop2_end = p_loop1_end + (num_pixels & 3);25__asm__ volatile (26".set push \n\t"27".set noreorder \n\t"28"beq %[argb_data], %[p_loop1_end], 3f \n\t"29" nop \n\t"30"0: \n\t"31"lw %[temp0], 0(%[argb_data]) \n\t"32"lw %[temp1], 4(%[argb_data]) \n\t"33"lw %[temp2], 8(%[argb_data]) \n\t"34"lw %[temp3], 12(%[argb_data]) \n\t"35"ext %[temp4], %[temp0], 8, 8 \n\t"36"ext %[temp5], %[temp1], 8, 8 \n\t"37"ext %[temp6], %[temp2], 8, 8 \n\t"38"ext %[temp7], %[temp3], 8, 8 \n\t"39"addiu %[argb_data], %[argb_data], 16 \n\t"40"replv.ph %[temp4], %[temp4] \n\t"41"replv.ph %[temp5], %[temp5] \n\t"42"replv.ph %[temp6], %[temp6] \n\t"43"replv.ph %[temp7], %[temp7] \n\t"44"subu.qb %[temp0], %[temp0], %[temp4] \n\t"45"subu.qb %[temp1], %[temp1], %[temp5] \n\t"46"subu.qb %[temp2], %[temp2], %[temp6] \n\t"47"subu.qb %[temp3], %[temp3], %[temp7] \n\t"48"sw %[temp0], -16(%[argb_data]) \n\t"49"sw %[temp1], -12(%[argb_data]) \n\t"50"sw %[temp2], -8(%[argb_data]) \n\t"51"bne %[argb_data], %[p_loop1_end], 0b \n\t"52" sw %[temp3], -4(%[argb_data]) \n\t"53"3: \n\t"54"beq %[argb_data], %[p_loop2_end], 2f \n\t"55" nop \n\t"56"1: \n\t"57"lw %[temp0], 0(%[argb_data]) \n\t"58"addiu %[argb_data], %[argb_data], 4 \n\t"59"ext %[temp4], %[temp0], 8, 8 \n\t"60"replv.ph %[temp4], %[temp4] \n\t"61"subu.qb %[temp0], %[temp0], %[temp4] \n\t"62"bne %[argb_data], %[p_loop2_end], 1b \n\t"63" sw %[temp0], -4(%[argb_data]) \n\t"64"2: \n\t"65".set pop \n\t"66: [argb_data]"+&r"(argb_data), [temp0]"=&r"(temp0),67[temp1]"=&r"(temp1), [temp2]"=&r"(temp2), [temp3]"=&r"(temp3),68[temp4]"=&r"(temp4), [temp5]"=&r"(temp5), [temp6]"=&r"(temp6),69[temp7]"=&r"(temp7)70: [p_loop1_end]"r"(p_loop1_end), [p_loop2_end]"r"(p_loop2_end)71: "memory"72);73}7475static WEBP_INLINE uint32_t ColorTransformDelta(int8_t color_pred,76int8_t color) {77return (uint32_t)((int)(color_pred) * color) >> 5;78}7980static void TransformColor_MIPSdspR2(81const VP8LMultipliers* WEBP_RESTRICT const m, uint32_t* WEBP_RESTRICT data,82int num_pixels) {83int temp0, temp1, temp2, temp3, temp4, temp5;84uint32_t argb, argb1, new_red, new_red1;85const uint32_t G_to_R = m->green_to_red_;86const uint32_t G_to_B = m->green_to_blue_;87const uint32_t R_to_B = m->red_to_blue_;88uint32_t* const p_loop_end = data + (num_pixels & ~1);89__asm__ volatile (90".set push \n\t"91".set noreorder \n\t"92"beq %[data], %[p_loop_end], 1f \n\t"93" nop \n\t"94"replv.ph %[temp0], %[G_to_R] \n\t"95"replv.ph %[temp1], %[G_to_B] \n\t"96"replv.ph %[temp2], %[R_to_B] \n\t"97"shll.ph %[temp0], %[temp0], 8 \n\t"98"shll.ph %[temp1], %[temp1], 8 \n\t"99"shll.ph %[temp2], %[temp2], 8 \n\t"100"shra.ph %[temp0], %[temp0], 8 \n\t"101"shra.ph %[temp1], %[temp1], 8 \n\t"102"shra.ph %[temp2], %[temp2], 8 \n\t"103"0: \n\t"104"lw %[argb], 0(%[data]) \n\t"105"lw %[argb1], 4(%[data]) \n\t"106"lhu %[new_red], 2(%[data]) \n\t"107"lhu %[new_red1], 6(%[data]) \n\t"108"precrq.qb.ph %[temp3], %[argb], %[argb1] \n\t"109"precr.qb.ph %[temp4], %[argb], %[argb1] \n\t"110"preceu.ph.qbra %[temp3], %[temp3] \n\t"111"preceu.ph.qbla %[temp4], %[temp4] \n\t"112"shll.ph %[temp3], %[temp3], 8 \n\t"113"shll.ph %[temp4], %[temp4], 8 \n\t"114"shra.ph %[temp3], %[temp3], 8 \n\t"115"shra.ph %[temp4], %[temp4], 8 \n\t"116"mul.ph %[temp5], %[temp3], %[temp0] \n\t"117"mul.ph %[temp3], %[temp3], %[temp1] \n\t"118"mul.ph %[temp4], %[temp4], %[temp2] \n\t"119"addiu %[data], %[data], 8 \n\t"120"ins %[new_red1], %[new_red], 16, 16 \n\t"121"ins %[argb1], %[argb], 16, 16 \n\t"122"shra.ph %[temp5], %[temp5], 5 \n\t"123"shra.ph %[temp3], %[temp3], 5 \n\t"124"shra.ph %[temp4], %[temp4], 5 \n\t"125"subu.ph %[new_red1], %[new_red1], %[temp5] \n\t"126"subu.ph %[argb1], %[argb1], %[temp3] \n\t"127"preceu.ph.qbra %[temp5], %[new_red1] \n\t"128"subu.ph %[argb1], %[argb1], %[temp4] \n\t"129"preceu.ph.qbra %[temp3], %[argb1] \n\t"130"sb %[temp5], -2(%[data]) \n\t"131"sb %[temp3], -4(%[data]) \n\t"132"sra %[temp5], %[temp5], 16 \n\t"133"sra %[temp3], %[temp3], 16 \n\t"134"sb %[temp5], -6(%[data]) \n\t"135"bne %[data], %[p_loop_end], 0b \n\t"136" sb %[temp3], -8(%[data]) \n\t"137"1: \n\t"138".set pop \n\t"139: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),140[temp3]"=&r"(temp3), [temp4]"=&r"(temp4), [temp5]"=&r"(temp5),141[new_red1]"=&r"(new_red1), [new_red]"=&r"(new_red),142[argb]"=&r"(argb), [argb1]"=&r"(argb1), [data]"+&r"(data)143: [G_to_R]"r"(G_to_R), [R_to_B]"r"(R_to_B),144[G_to_B]"r"(G_to_B), [p_loop_end]"r"(p_loop_end)145: "memory", "hi", "lo"146);147148if (num_pixels & 1) {149const uint32_t argb_ = data[0];150const uint32_t green = argb_ >> 8;151const uint32_t red = argb_ >> 16;152uint32_t new_blue = argb_;153new_red = red;154new_red -= ColorTransformDelta(m->green_to_red_, green);155new_red &= 0xff;156new_blue -= ColorTransformDelta(m->green_to_blue_, green);157new_blue -= ColorTransformDelta(m->red_to_blue_, red);158new_blue &= 0xff;159data[0] = (argb_ & 0xff00ff00u) | (new_red << 16) | (new_blue);160}161}162163static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,164uint8_t red_to_blue,165uint32_t argb) {166const uint32_t green = argb >> 8;167const uint32_t red = argb >> 16;168uint8_t new_blue = argb;169new_blue -= ColorTransformDelta(green_to_blue, green);170new_blue -= ColorTransformDelta(red_to_blue, red);171return (new_blue & 0xff);172}173174static void CollectColorBlueTransforms_MIPSdspR2(175const uint32_t* WEBP_RESTRICT argb, int stride,176int tile_width, int tile_height,177int green_to_blue, int red_to_blue, uint32_t histo[]) {178const int rtb = (red_to_blue << 16) | (red_to_blue & 0xffff);179const int gtb = (green_to_blue << 16) | (green_to_blue & 0xffff);180const uint32_t mask = 0xff00ffu;181while (tile_height-- > 0) {182int x;183const uint32_t* p_argb = argb;184argb += stride;185for (x = 0; x < (tile_width >> 1); ++x) {186int temp0, temp1, temp2, temp3, temp4, temp5, temp6;187__asm__ volatile (188"lw %[temp0], 0(%[p_argb]) \n\t"189"lw %[temp1], 4(%[p_argb]) \n\t"190"precr.qb.ph %[temp2], %[temp0], %[temp1] \n\t"191"ins %[temp1], %[temp0], 16, 16 \n\t"192"shra.ph %[temp2], %[temp2], 8 \n\t"193"shra.ph %[temp3], %[temp1], 8 \n\t"194"mul.ph %[temp5], %[temp2], %[rtb] \n\t"195"mul.ph %[temp6], %[temp3], %[gtb] \n\t"196"and %[temp4], %[temp1], %[mask] \n\t"197"addiu %[p_argb], %[p_argb], 8 \n\t"198"shra.ph %[temp5], %[temp5], 5 \n\t"199"shra.ph %[temp6], %[temp6], 5 \n\t"200"subu.qb %[temp2], %[temp4], %[temp5] \n\t"201"subu.qb %[temp2], %[temp2], %[temp6] \n\t"202: [p_argb]"+&r"(p_argb), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),203[temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4),204[temp5]"=&r"(temp5), [temp6]"=&r"(temp6)205: [rtb]"r"(rtb), [gtb]"r"(gtb), [mask]"r"(mask)206: "memory", "hi", "lo"207);208++histo[(uint8_t)(temp2 >> 16)];209++histo[(uint8_t)temp2];210}211if (tile_width & 1) {212++histo[TransformColorBlue(green_to_blue, red_to_blue, *p_argb)];213}214}215}216217static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,218uint32_t argb) {219const uint32_t green = argb >> 8;220uint32_t new_red = argb >> 16;221new_red -= ColorTransformDelta(green_to_red, green);222return (new_red & 0xff);223}224225static void CollectColorRedTransforms_MIPSdspR2(226const uint32_t* WEBP_RESTRICT argb, int stride,227int tile_width, int tile_height, int green_to_red, uint32_t histo[]) {228const int gtr = (green_to_red << 16) | (green_to_red & 0xffff);229while (tile_height-- > 0) {230int x;231const uint32_t* p_argb = argb;232argb += stride;233for (x = 0; x < (tile_width >> 1); ++x) {234int temp0, temp1, temp2, temp3, temp4;235__asm__ volatile (236"lw %[temp0], 0(%[p_argb]) \n\t"237"lw %[temp1], 4(%[p_argb]) \n\t"238"precrq.ph.w %[temp4], %[temp0], %[temp1] \n\t"239"ins %[temp1], %[temp0], 16, 16 \n\t"240"shra.ph %[temp3], %[temp1], 8 \n\t"241"mul.ph %[temp2], %[temp3], %[gtr] \n\t"242"addiu %[p_argb], %[p_argb], 8 \n\t"243"shra.ph %[temp2], %[temp2], 5 \n\t"244"subu.qb %[temp2], %[temp4], %[temp2] \n\t"245: [p_argb]"+&r"(p_argb), [temp0]"=&r"(temp0), [temp1]"=&r"(temp1),246[temp2]"=&r"(temp2), [temp3]"=&r"(temp3), [temp4]"=&r"(temp4)247: [gtr]"r"(gtr)248: "memory", "hi", "lo"249);250++histo[(uint8_t)(temp2 >> 16)];251++histo[(uint8_t)temp2];252}253if (tile_width & 1) {254++histo[TransformColorRed(green_to_red, *p_argb)];255}256}257}258259//------------------------------------------------------------------------------260// Entry point261262extern void VP8LEncDspInitMIPSdspR2(void);263264WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInitMIPSdspR2(void) {265VP8LSubtractGreenFromBlueAndRed = SubtractGreenFromBlueAndRed_MIPSdspR2;266VP8LTransformColor = TransformColor_MIPSdspR2;267VP8LCollectColorBlueTransforms = CollectColorBlueTransforms_MIPSdspR2;268VP8LCollectColorRedTransforms = CollectColorRedTransforms_MIPSdspR2;269}270271#else // !WEBP_USE_MIPS_DSP_R2272273WEBP_DSP_INIT_STUB(VP8LEncDspInitMIPSdspR2)274275#endif // WEBP_USE_MIPS_DSP_R2276277278