@@ -54,11 +54,10 @@ function jpeg_decode(
54
54
@assert infile. ptr != C_NULL
55
55
out_CT, jpeg_cls = _jpeg_out_color_space (CT)
56
56
57
- local cinfo, out
57
+ cinfo_ref = Ref (LibJpeg. jpeg_decompress_struct ())
58
+ jerr = Ref {LibJpeg.jpeg_error_mgr} ()
58
59
try
59
- cinfo = LibJpeg. jpeg_decompress_struct ()
60
- cinfo_ref = Ref (cinfo)
61
- jerr = Ref {LibJpeg.jpeg_error_mgr} ()
60
+ cinfo = cinfo_ref[]
62
61
cinfo. err = LibJpeg. jpeg_std_error (jerr)
63
62
LibJpeg. jpeg_create_decompress (cinfo_ref)
64
63
LibJpeg. jpeg_stdio_src (cinfo_ref, infile)
@@ -79,60 +78,61 @@ function jpeg_decode(
79
78
@assert out_ndims == length (out_CT) " Suspicous output color space: $cinfo .out_color_space"
80
79
81
80
out = Matrix {out_CT} (undef, out_size)
82
- _jpeg_decode! (out, cinfo)
81
+ _jpeg_decode! (out, cinfo_ref)
82
+
83
+ if out_CT <: CT
84
+ return transpose ? out : permutedims (out, (2 , 1 ))
85
+ else
86
+ return transpose ? CT .(out) : CT .(PermutedDimsArray (out, (2 , 1 )))
87
+ end
83
88
finally
84
- LibJpeg. jpeg_destroy_decompress (Ref (cinfo) )
89
+ LibJpeg. jpeg_destroy_decompress (cinfo_ref )
85
90
ccall (:fclose , Cint, (Ptr{Libc. FILE},), infile)
86
91
end
87
-
88
- if out_CT <: CT
89
- return transpose ? out : permutedims (out, (2 , 1 ))
90
- else
91
- return transpose ? CT .(out) : CT .(PermutedDimsArray (out, (2 , 1 )))
92
- end
93
92
end
94
93
function jpeg_decode (filename:: AbstractString ; kwargs... )
95
94
return jpeg_decode (_default_out_color_space (filename), filename; kwargs... )
96
95
end
97
96
98
- function _jpeg_decode! (out:: Matrix{<:Colorant} , cinfo:: LibJpeg.jpeg_decompress_struct )
99
- cinfo_ref = Ref (cinfo)
100
-
97
+ function _jpeg_decode! (out:: Matrix{<:Colorant} , cinfo_ref:: Ref{LibJpeg.jpeg_decompress_struct} )
101
98
row_stride = size (out, 1 ) * length (eltype (out))
102
99
buf = Vector {UInt8} (undef, row_stride)
100
+ buf_ref = Ref (pointer (buf))
103
101
out_uint8 = reinterpret (UInt8, out)
104
102
103
+ cinfo = cinfo_ref[]
105
104
LibJpeg. jpeg_start_decompress (cinfo_ref)
106
105
while cinfo. output_scanline < cinfo. output_height
107
106
# TODO (johnnychen94): try if we can directly write to `out` without using `buf`
108
- GC. @preserve buf LibJpeg. jpeg_read_scanlines (cinfo_ref, Ref ( pointer (buf)) , 1 )
107
+ GC. @preserve buf LibJpeg. jpeg_read_scanlines (cinfo_ref, buf_ref , 1 )
109
108
copyto! (out_uint8, (cinfo. output_scanline- 1 ) * row_stride + 1 , buf, 1 , row_stride)
110
109
end
111
110
LibJpeg. jpeg_finish_decompress (cinfo_ref)
112
111
113
112
return out
114
113
end
115
114
115
+
116
+ _jpeg_decode! (out:: Matrix{<:Colorant} , cinfo:: LibJpeg.jpeg_decompress_struct ) = _jpeg_decode! (out, Ref (cinfo))
117
+
116
118
# libjpeg-turbo only supports ratio M/8 with M from 1 to 16
117
119
const _allowed_scale_ratios = ntuple (i-> i// 8 , 16 )
118
120
_cal_scale_ratio (r:: Real ) = _allowed_scale_ratios[findmin (x-> abs (x- r), _allowed_scale_ratios)[2 ]]
119
121
120
122
function _default_out_color_space (filename:: AbstractString )
121
123
infile = ccall (:fopen , Libc. FILE, (Cstring, Cstring), filename, " rb" )
122
124
@assert infile. ptr != C_NULL
123
- local cinfo
125
+ cinfo_ref = Ref (LibJpeg. jpeg_decompress_struct ())
126
+ jerr = Ref {LibJpeg.jpeg_error_mgr} ()
124
127
try
125
- cinfo = LibJpeg. jpeg_decompress_struct ()
126
- cinfo_ref = Ref (cinfo)
127
- jerr = Ref {LibJpeg.jpeg_error_mgr} ()
128
- cinfo. err = LibJpeg. jpeg_std_error (jerr)
128
+ cinfo_ref[]. err = LibJpeg. jpeg_std_error (jerr)
129
129
LibJpeg. jpeg_create_decompress (cinfo_ref)
130
130
LibJpeg. jpeg_stdio_src (cinfo_ref, infile)
131
131
LibJpeg. jpeg_read_header (cinfo_ref, true )
132
132
LibJpeg. jpeg_calc_output_dimensions (cinfo_ref)
133
- return jpeg_color_space (cinfo . out_color_space)
133
+ return jpeg_color_space (cinfo_ref[] . out_color_space)
134
134
finally
135
- LibJpeg. jpeg_destroy_decompress (Ref (cinfo) )
135
+ LibJpeg. jpeg_destroy_decompress (cinfo_ref )
136
136
ccall (:fclose , Cint, (Ptr{Libc. FILE},), infile)
137
137
end
138
138
end
0 commit comments