13e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower/* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 23e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 33e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerLicensed under the Apache License, Version 2.0 (the "License"); 43e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFloweryou may not use this file except in compliance with the License. 53e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerYou may obtain a copy of the License at 63e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 73e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower http://www.apache.org/licenses/LICENSE-2.0 83e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 93e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerUnless required by applicable law or agreed to in writing, software 103e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerdistributed under the License is distributed on an "AS IS" BASIS, 113e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerSee the License for the specific language governing permissions and 133e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerlimitations under the License. 143e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower==============================================================================*/ 151019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#define EIGEN_USE_THREADS 161019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower 171019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#if GOOGLE_CUDA 181019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#define EIGEN_USE_GPU 191019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#endif 201019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower 211019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#include "tensorflow/core/kernels/adjust_saturation_op.h" 223e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include <memory> 233e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" 243e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/framework/op_kernel.h" 253e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/framework/register_types.h" 263e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/framework/tensor.h" 273e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/framework/tensor_shape.h" 283e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/framework/types.h" 293e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/lib/core/status.h" 303e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/platform/logging.h" 313e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower#include "tensorflow/core/util/work_sharder.h" 323e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 333e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowernamespace tensorflow { 343e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 353e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowertypedef Eigen::ThreadPoolDevice CPUDevice; 363e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowertypedef Eigen::GpuDevice GPUDevice; 373e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 383e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerclass AdjustSaturationOpBase : public OpKernel { 393e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower protected: 406882effb863dcd0da00d3287959deac46734a0b2A. Unique TensorFlower explicit AdjustSaturationOpBase(OpKernelConstruction* context) 416882effb863dcd0da00d3287959deac46734a0b2A. Unique TensorFlower : OpKernel(context) {} 423e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 433e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower struct ComputeOptions { 443e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const Tensor* input; 453e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const Tensor* scale; 463e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower Tensor* output; 473e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower int64 channel_count; 483e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower }; 493e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 503e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower virtual void DoCompute(OpKernelContext* context, 513e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const ComputeOptions& options) = 0; 523e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 533e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower void Compute(OpKernelContext* context) override { 543e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const Tensor& input = context->input(0); 553e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const Tensor& scale = context->input(1); 563e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower OP_REQUIRES(context, input.dims() >= 3, 573e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower errors::InvalidArgument("input must be at least 3-D, got shape", 583e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower input.shape().DebugString())); 593e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower OP_REQUIRES(context, TensorShapeUtils::IsScalar(scale.shape()), 603e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower errors::InvalidArgument("scale must be scalar: ", 613e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower scale.shape().DebugString())); 623e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower auto channels = input.dim_size(input.dims() - 1); 633e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower OP_REQUIRES( 643e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower context, channels == 3, 653e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower errors::InvalidArgument("input must have 3 channels but instead has ", 663e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower channels, " channels.")); 673e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 683e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower Tensor* output = nullptr; 693e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower OP_REQUIRES_OK(context, 703e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower context->allocate_output(0, input.shape(), &output)); 713e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 723e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower if (input.NumElements() > 0) { 733e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const int64 channel_count = input.NumElements() / channels; 743e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower ComputeOptions options; 753e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower options.input = &input; 763e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower options.scale = &scale; 773e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower options.output = output; 783e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower options.channel_count = channel_count; 793e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower DoCompute(context, options); 803e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 813e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 823e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower}; 833e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 843e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowertemplate <class Device> 853e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerclass AdjustSaturationOp; 863e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 873e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowernamespace internal { 883e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerstatic void rgb_to_hsv(float r, float g, float b, float* h, float* s, 893e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float* v) { 903e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float vv = std::max(r, std::max(g, b)); 913e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float range = vv - std::min(r, std::min(g, b)); 923e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower if (vv > 0) { 933e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *s = range / vv; 943e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } else { 953e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *s = 0; 963e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 973e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float norm = 1.0f / (6.0f * range); 983e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float hh; 993e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower if (r == vv) { 1003e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower hh = norm * (g - b); 1013e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } else if (g == vv) { 1023e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower hh = norm * (b - r) + 2.0 / 6.0; 1033e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } else { 1043e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower hh = norm * (r - g) + 4.0 / 6.0; 1053e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 1063e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower if (range <= 0.0) { 1073e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower hh = 0; 1083e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 1093e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower if (hh < 0.0) { 1103e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower hh = hh + 1; 1113e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 1123e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *v = vv; 1133e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *h = hh; 1143e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower} 1153e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 1163e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower// Algorithm from wikipedia, https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV 1173e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerstatic void hsv_to_rgb(float h, float s, float v, float* r, float* g, 1183e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float* b) { 1193e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float c = s * v; 1203e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float m = v - c; 1213e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float dh = h * 6; 1223e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float rr, gg, bb; 1233e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower int h_category = static_cast<int>(dh); 1243e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float fmodu = dh; 1253e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower while (fmodu <= 0) { 1263e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower fmodu += 2.0f; 1273e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 1283e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower while (fmodu >= 2.0f) { 1293e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower fmodu -= 2.0f; 1303e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 1313e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float x = c * (1 - std::abs(fmodu - 1)); 1323e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower switch (h_category) { 1333e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower case 0: 1343e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = c; 1353e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = x; 1363e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = 0; 1373e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower break; 1383e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower case 1: 1393e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = x; 1403e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = c; 1413e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = 0; 1423e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower break; 1433e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower case 2: 1443e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = 0; 1453e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = c; 1463e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = x; 1473e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower break; 1483e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower case 3: 1493e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = 0; 1503e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = x; 1513e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = c; 1523e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower break; 1533e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower case 4: 1543e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = x; 1553e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = 0; 1563e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = c; 1573e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower break; 1583e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower case 5: 1593e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = c; 1603e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = 0; 1613e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = x; 1623e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower break; 1633e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower default: 1643e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower rr = 0; 1653e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower gg = 0; 1663e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower bb = 0; 1673e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 1683e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *r = rr + m; 1693e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *g = gg + m; 1703e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *b = bb + m; 1713e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower} 1723e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 1733e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower} // namespace internal 1743e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 1753e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowertemplate <> 1763e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerclass AdjustSaturationOp<CPUDevice> : public AdjustSaturationOpBase { 1773e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower public: 1783e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower explicit AdjustSaturationOp(OpKernelConstruction* context) 1793e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower : AdjustSaturationOpBase(context) {} 1803e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 1813e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower void DoCompute(OpKernelContext* context, 1823e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const ComputeOptions& options) override { 1833e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const Tensor* input = options.input; 1843e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const Tensor* scale = options.scale; 1853e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower Tensor* output = options.output; 1863e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const int64 channel_count = options.channel_count; 1873e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower static const int kChannelSize = 3; 1883e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower auto input_data = input->shaped<float, 2>({channel_count, kChannelSize}); 1893e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const float scale_h = scale->scalar<float>()(); 1903e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower auto output_data = output->shaped<float, 2>({channel_count, kChannelSize}); 1913e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const int kCostPerChannel = 10; 1923e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const DeviceBase::CpuWorkerThreads& worker_threads = 1933e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower *context->device()->tensorflow_cpu_worker_threads(); 1943e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower Shard(worker_threads.num_threads, worker_threads.workers, channel_count, 195982549ea3423df4270ff154e5c764beb43d472daRasmus Munk Larsen kCostPerChannel, 196982549ea3423df4270ff154e5c764beb43d472daRasmus Munk Larsen [channel_count, &input_data, &output_data, scale_h]( 197982549ea3423df4270ff154e5c764beb43d472daRasmus Munk Larsen int64 start_channel, int64 end_channel) { 1983e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower const float* p = input_data.data() + start_channel * kChannelSize; 1993e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float* q = output_data.data() + start_channel * kChannelSize; 2003e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower for (int i = start_channel; i < end_channel; i++) { 2013e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower float h, s, v; 2023e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower // Convert the RGB color to Hue/V-range. 2033e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower internal::rgb_to_hsv(p[0], p[1], p[2], &h, &s, &v); 2043e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower s = std::min(1.0f, std::max(0.0f, s * scale_h)); 2053e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower // Convert the hue and v-range back into RGB. 2063e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower internal::hsv_to_rgb(h, s, v, q, q + 1, q + 2); 2073e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower p += kChannelSize; 2083e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower q += kChannelSize; 2093e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 2103e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower }); 2113e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower } 2123e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower}; 2133e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 2143e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlowerREGISTER_KERNEL_BUILDER(Name("AdjustSaturation").Device(DEVICE_CPU), 2153e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower AdjustSaturationOp<CPUDevice>); 2163e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower 2171019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#if GOOGLE_CUDA 2181019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlowertemplate <> 2191019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlowerclass AdjustSaturationOp<GPUDevice> : public AdjustSaturationOpBase { 2201019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower public: 2211019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower explicit AdjustSaturationOp(OpKernelConstruction* context) 2221019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower : AdjustSaturationOpBase(context) {} 2231019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower 2241019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower void DoCompute(OpKernelContext* context, 2251019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const ComputeOptions& options) override { 2261019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const Tensor* input = options.input; 2271019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const Tensor* scale = options.scale; 2281019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower Tensor* output = options.output; 2291019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const int64 number_of_elements = input->NumElements(); 2301019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower GPUDevice device = context->eigen_gpu_device(); 2311019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const auto stream = device.stream(); 2321019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower OP_REQUIRES(context, stream, errors::Internal("No GPU stream available.")); 2331019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower if (number_of_elements > 0) { 2341019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const float* input_data = input->flat<float>().data(); 2351019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower const float* scale_data = scale->flat<float>().data(); 2361019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower float* const output_data = output->flat<float>().data(); 2371019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower functor::AdjustSaturationGPU()(&device, number_of_elements, input_data, 2381019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower scale_data, output_data); 2391019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower } 2401019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower } 2411019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower}; 2421019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower 2431019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlowerREGISTER_KERNEL_BUILDER(Name("AdjustSaturation").Device(DEVICE_GPU), 2441019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower AdjustSaturationOp<GPUDevice>); 2451019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower 2461019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower#endif 2471019621df2b8e7f516be13de3fbb4fb2833a686aA. Unique TensorFlower 2483e265dbe37ea49dba02fa4de6bec34d14a2ac241A. Unique TensorFlower} // namespace tensorflow 249