11#include " encode_jpeg.h"
22
3+ #include < torch/csrc/stable/library.h>
4+ #include < torch/csrc/stable/ops.h>
35#include < torch/headeronly/util/Exception.h>
46
57#include < optional>
68
9+ #include " ../common_stable.h"
710#include " common_jpeg.h"
811
912namespace vision {
1013namespace image {
1114
1215#if !JPEG_FOUND
1316
14- torch::Tensor encode_jpeg (const torch::Tensor& data, int64_t quality) {
17+ torch::stable::Tensor encode_jpeg (
18+ const torch::stable::Tensor& data,
19+ int64_t quality) {
1520 STD_TORCH_CHECK (
1621 false , " encode_jpeg: torchvision not compiled with libjpeg support" );
1722}
@@ -28,9 +33,9 @@ using JpegSizeType = size_t;
2833
2934using namespace detail ;
3035
31- torch::Tensor encode_jpeg ( const torch ::Tensor& data, int64_t quality) {
32- C10_LOG_API_USAGE_ONCE (
33- " torchvision.csrc.io.image.cpu.encode_jpeg.encode_jpeg " );
36+ torch::stable ::Tensor encode_jpeg (
37+ const torch::stable::Tensor& data,
38+ int64_t quality) {
3439 // Define compression structures and error handling
3540 struct jpeg_compress_struct cinfo {};
3641 struct torch_jpeg_error_mgr jerr {};
@@ -43,7 +48,7 @@ torch::Tensor encode_jpeg(const torch::Tensor& data, int64_t quality) {
4348 // unwind C++ stack frames, so destructors of objects created after setjmp
4449 // won't run. We use std::optional to declare tensors before setjmp while
4550 // deferring construction, and explicitly reset them on the error path.
46- std::optional<torch::Tensor> input;
51+ std::optional<torch::stable:: Tensor> input;
4752
4853 cinfo.err = jpeg_std_error (&jerr.pub );
4954 jerr.pub .error_exit = torch_jpeg_error_exit;
@@ -63,12 +68,12 @@ torch::Tensor encode_jpeg(const torch::Tensor& data, int64_t quality) {
6368 }
6469
6570 // Check that the input tensor is on CPU
66- STD_TORCH_CHECK (
67- data.device () == torch::kCPU , " Input tensor should be on CPU" );
71+ STD_TORCH_CHECK (data.is_cpu (), " Input tensor should be on CPU" );
6872
6973 // Check that the input tensor dtype is uint8
7074 STD_TORCH_CHECK (
71- data.dtype () == torch::kU8 , " Input tensor dtype should be uint8" );
75+ data.scalar_type () == torch::headeronly::ScalarType::Byte,
76+ " Input tensor dtype should be uint8" );
7277
7378 // Check that the input tensor is 3-dimensional
7479 STD_TORCH_CHECK (
@@ -78,7 +83,7 @@ torch::Tensor encode_jpeg(const torch::Tensor& data, int64_t quality) {
7883 int channels = data.size (0 );
7984 int height = data.size (1 );
8085 int width = data.size (2 );
81- input = data. permute ( {1 , 2 , 0 }). contiguous ( );
86+ input = torch::stable::contiguous ( stable_permute (data, {1 , 2 , 0 }));
8287
8388 STD_TORCH_CHECK (
8489 channels == 1 || channels == 3 ,
@@ -104,7 +109,7 @@ torch::Tensor encode_jpeg(const torch::Tensor& data, int64_t quality) {
104109 jpeg_start_compress (&cinfo, TRUE );
105110
106111 auto stride = width * channels;
107- auto ptr = input->data_ptr <uint8_t >();
112+ auto ptr = input->mutable_data_ptr <uint8_t >();
108113
109114 // Encode JPEG file
110115 while (cinfo.next_scanline < cinfo.image_height ) {
@@ -115,13 +120,25 @@ torch::Tensor encode_jpeg(const torch::Tensor& data, int64_t quality) {
115120 jpeg_finish_compress (&cinfo);
116121 jpeg_destroy_compress (&cinfo);
117122
118- torch::TensorOptions options = torch::TensorOptions{torch::kU8 };
119- auto out_tensor =
120- torch::from_blob (jpegBuf, {(long )jpegSize}, ::free, options);
123+ auto out_tensor = torch::stable::from_blob (
124+ jpegBuf,
125+ {static_cast <int64_t >(jpegSize)},
126+ {1 },
127+ torch::stable::Device (torch::headeronly::DeviceType::CPU ),
128+ torch::headeronly::ScalarType::Byte,
129+ ::free);
121130 jpegBuf = nullptr ;
122131 return out_tensor;
123132}
124133#endif
125134
135+ STABLE_TORCH_LIBRARY_FRAGMENT (image, m) {
136+ m.def (" encode_jpeg(Tensor data, int quality) -> Tensor" );
137+ }
138+
139+ STABLE_TORCH_LIBRARY_IMPL (image, CompositeExplicitAutograd, m) {
140+ m.impl (" encode_jpeg" , TORCH_BOX (&encode_jpeg));
141+ }
142+
126143} // namespace image
127144} // namespace vision
0 commit comments