180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkUnitMappers.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(SkUnitMapper)
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDiscreteMapper::SkDiscreteMapper(int segments) {
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (segments < 2) {
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fSegments = 0;
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fScale = 0;
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (segments > 0xFFFF) {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            segments = 0xFFFF;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fSegments = segments;
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fScale = SK_Fract1 / (segments - 1);
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint16_t SkDiscreteMapper::mapUnit16(uint16_t input) {
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed x = input * fSegments >> 16;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x = x * fScale >> 14;
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x += x << 15 >> 31; // map 0x10000 to 0xFFFF
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkToU16(x);
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDiscreteMapper::SkDiscreteMapper(SkFlattenableReadBuffer& rb)
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        : SkUnitMapper(rb) {
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fSegments = rb.readInt();
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fScale = rb.read32();
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkDiscreteMapper::flatten(SkFlattenableWriteBuffer& wb) const {
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::flatten(wb);
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    wb.writeInt(fSegments);
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    wb.write32(fScale);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint16_t SkCosineMapper::mapUnit16(uint16_t input)
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /*  we want to call cosine(input * pi/2) treating input as [0...1)
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        however, the straight multitply would overflow 32bits since input is
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        16bits and pi/2 is 17bits, so we shift down our pi const before we mul
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    */
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed rads = (unsigned)(input * (SK_FixedPI >> 2)) >> 15;
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed x = SkFixedCos(rads);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    x += x << 15 >> 31; // map 0x10000 to 0xFFFF
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkToU16(x);
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCosineMapper::SkCosineMapper(SkFlattenableReadBuffer& rb)
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : SkUnitMapper(rb) {}
62