| 149 | } |
| 150 | |
| 151 | void Compute(OpKernelContext* context) override { |
| 152 | const Tensor& contents = context->input(0); |
| 153 | OP_REQUIRES(context, TensorShapeUtils::IsScalar(contents.shape()), |
| 154 | errors::InvalidArgument("contents must be scalar, got shape ", |
| 155 | contents.shape().DebugString())); |
| 156 | |
| 157 | // Determine format |
| 158 | const StringPiece input = contents.scalar<tstring>()(); |
| 159 | const auto magic = ClassifyFileFormat(input); |
| 160 | OP_REQUIRES( |
| 161 | context, |
| 162 | magic == kJpgFormat || magic == kPngFormat || magic == kGifFormat, |
| 163 | errors::InvalidArgument("Expected image (JPEG, PNG, or GIF), got ", |
| 164 | FileFormatString(magic, input))); |
| 165 | OP_REQUIRES(context, input.size() <= std::numeric_limits<int>::max(), |
| 166 | errors::InvalidArgument( |
| 167 | FileFormatString(magic, input), |
| 168 | " contents are too large for int: ", input.size())); |
| 169 | OP_REQUIRES(context, magic == kPngFormat || channel_bits_ == 8, |
| 170 | errors::InvalidArgument(FileFormatString(magic, input), |
| 171 | " does not support uint16 output")); |
| 172 | |
| 173 | switch (magic) { |
| 174 | case kJpgFormat: |
| 175 | DecodeJpeg(context, input); |
| 176 | break; |
| 177 | case kPngFormat: |
| 178 | DecodePng(context, input); |
| 179 | break; |
| 180 | case kGifFormat: |
| 181 | DecodeGif(context, input); |
| 182 | break; |
| 183 | default: |
| 184 | LOG(FATAL) << "Should never get here after check above"; |
| 185 | break; |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | void DecodeJpeg(OpKernelContext* context, StringPiece input) { |
| 190 | OP_REQUIRES(context, channels_ == 0 || channels_ == 1 || channels_ == 3, |
nothing calls this directly
no test coverage detected