| 50 | } |
| 51 | |
| 52 | void Compute(OpKernelContext* context) override { |
| 53 | const Tensor& image = context->input(0); |
| 54 | OP_REQUIRES(context, image.dims() == 3, |
| 55 | errors::InvalidArgument("image must be 3-dimensional", |
| 56 | image.shape().DebugString())); |
| 57 | OP_REQUIRES( |
| 58 | context, |
| 59 | FastBoundsCheck(image.NumElements(), std::numeric_limits<int32>::max()), |
| 60 | errors::InvalidArgument("image cannot have >= int32 max elements")); |
| 61 | const int32 height = static_cast<int32>(image.dim_size(0)); |
| 62 | const int32 width = static_cast<int32>(image.dim_size(1)); |
| 63 | const int32 channels = static_cast<int32>(image.dim_size(2)); |
| 64 | |
| 65 | // In some cases, we pass width*channels*2 to png. |
| 66 | const int32 max_row_width = std::numeric_limits<int32>::max() / 2; |
| 67 | |
| 68 | OP_REQUIRES(context, FastBoundsCheck(width * channels, max_row_width), |
| 69 | errors::InvalidArgument("image too wide to encode")); |
| 70 | |
| 71 | OP_REQUIRES(context, channels >= 1 && channels <= 4, |
| 72 | errors::InvalidArgument( |
| 73 | "image must have 1, 2, 3, or 4 channels, got ", channels)); |
| 74 | |
| 75 | // Encode image to png string |
| 76 | Tensor* output = nullptr; |
| 77 | OP_REQUIRES_OK(context, |
| 78 | context->allocate_output(0, TensorShape({}), &output)); |
| 79 | if (desired_channel_bits_ == 8) { |
| 80 | OP_REQUIRES(context, |
| 81 | png::WriteImageToBuffer(image.flat<uint8>().data(), width, |
| 82 | height, width * channels, channels, |
| 83 | desired_channel_bits_, compression_, |
| 84 | &output->scalar<string>()(), nullptr), |
| 85 | errors::Internal("PNG encoding failed")); |
| 86 | } else { |
| 87 | OP_REQUIRES(context, |
| 88 | png::WriteImageToBuffer( |
| 89 | image.flat<uint16>().data(), width, height, |
| 90 | width * channels * 2, channels, desired_channel_bits_, |
| 91 | compression_, &output->scalar<string>()(), nullptr), |
| 92 | errors::Internal("PNG encoding failed")); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | private: |
| 97 | int compression_; |
nothing calls this directly
no test coverage detected