Skip to content

Commit 8e0e8fe

Browse files
authored
conva: fix a crash with {u,}{short,int} images (#4055)
{u,}{short,int} images should use {u,}short as an intermediate type when the length of the longest line is below 256. Resolves: #1162.
1 parent 456353b commit 8e0e8fe

File tree

2 files changed

+39
-25
lines changed

2 files changed

+39
-25
lines changed

ChangeLog

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- fix pipe read limit
88
- fix a rare crash on Windows in highly threaded applications [Julianiolo]
99
- vipssave: fix infinite loop on Windows with large images [pdbourke]
10+
- conva: fix a crash with {u,}{short,int} images [erdmann]
1011
- fix vips_image_get_string
1112
- heifsave: fix lossless mode [kleisauke]
1213

libvips/convolution/conva.c

+38-25
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ typedef struct {
177177

178178
/* The horizontal lines we gather. hline[3] writes to band 3 in the
179179
* intermediate image. max_line is the length of the longest hline:
180-
* over 256 and we need to use an int intermediate for 8-bit images.
180+
* over 256 and we need to use an int intermediate for integer images.
181181
*/
182182
int n_hline;
183183
HLine hline[MAX_LINES];
@@ -933,33 +933,39 @@ vips_conva_hgenerate(VipsRegion *out_region,
933933
break;
934934

935935
case VIPS_FORMAT_USHORT:
936-
HCONV(unsigned short, unsigned int);
936+
if (conva->max_line < 256)
937+
HCONV(unsigned short, unsigned short);
938+
else
939+
HCONV(unsigned short, unsigned int);
937940
break;
938941

939942
case VIPS_FORMAT_SHORT:
940-
HCONV(signed short, signed int);
943+
if (conva->max_line < 256)
944+
HCONV(signed short, signed short);
945+
else
946+
HCONV(signed short, signed int);
941947
break;
942948

943949
case VIPS_FORMAT_UINT:
944-
HCONV(unsigned int, unsigned int);
950+
if (conva->max_line < 256)
951+
HCONV(unsigned int, unsigned short);
952+
else
953+
HCONV(unsigned int, unsigned int);
945954
break;
946955

947956
case VIPS_FORMAT_INT:
948-
HCONV(signed int, signed int);
957+
if (conva->max_line < 256)
958+
HCONV(signed int, signed short);
959+
else
960+
HCONV(signed int, signed int);
949961
break;
950962

951963
case VIPS_FORMAT_FLOAT:
952-
HCONV(float, float);
953-
break;
954-
955-
case VIPS_FORMAT_DOUBLE:
956-
HCONV(double, double);
957-
break;
958-
959964
case VIPS_FORMAT_COMPLEX:
960965
HCONV(float, float);
961966
break;
962967

968+
case VIPS_FORMAT_DOUBLE:
963969
case VIPS_FORMAT_DPCOMPLEX:
964970
HCONV(double, double);
965971
break;
@@ -993,7 +999,7 @@ vips_conva_horizontal(VipsConva *conva, VipsImage *in, VipsImage **out)
993999
}
9941000
(*out)->Bands *= conva->n_hline;
9951001

996-
/* Short u?char lines can use u?short intermediate.
1002+
/* Short {u,}{char,short,int} lines can use {u,}short as intermediate.
9971003
*/
9981004
if (vips_band_format_isuint(in->BandFmt))
9991005
(*out)->BandFmt = conva->max_line < 256
@@ -1175,34 +1181,41 @@ vips_conva_vgenerate(VipsRegion *out_region,
11751181
break;
11761182

11771183
case VIPS_FORMAT_USHORT:
1178-
VCONV(unsigned int,
1179-
unsigned int, unsigned short, CLIP_USHORT);
1184+
if (conva->max_line < 256)
1185+
VCONV(unsigned int,
1186+
unsigned short, unsigned short, CLIP_USHORT);
1187+
else
1188+
VCONV(unsigned int,
1189+
unsigned int, unsigned short, CLIP_USHORT);
11801190
break;
11811191

11821192
case VIPS_FORMAT_SHORT:
1183-
VCONV(signed int, signed int, signed short, CLIP_SHORT);
1193+
if (conva->max_line < 256)
1194+
VCONV(signed int, signed short, signed short, CLIP_SHORT);
1195+
else
1196+
VCONV(signed int, signed int, signed short, CLIP_SHORT);
11841197
break;
11851198

11861199
case VIPS_FORMAT_UINT:
1187-
VCONV(unsigned int, unsigned int, unsigned int, CLIP_NONE);
1200+
if (conva->max_line < 256)
1201+
VCONV(unsigned int, unsigned short, unsigned int, CLIP_SHORT);
1202+
else
1203+
VCONV(unsigned int, unsigned int, unsigned int, CLIP_NONE);
11881204
break;
11891205

11901206
case VIPS_FORMAT_INT:
1191-
VCONV(signed int, signed int, signed int, CLIP_NONE);
1207+
if (conva->max_line < 256)
1208+
VCONV(signed int, signed short, signed int, CLIP_NONE);
1209+
else
1210+
VCONV(signed int, signed int, signed int, CLIP_NONE);
11921211
break;
11931212

11941213
case VIPS_FORMAT_FLOAT:
1195-
VCONV(float, float, float, CLIP_NONE);
1196-
break;
1197-
1198-
case VIPS_FORMAT_DOUBLE:
1199-
VCONV(double, double, double, CLIP_NONE);
1200-
break;
1201-
12021214
case VIPS_FORMAT_COMPLEX:
12031215
VCONV(float, float, float, CLIP_NONE);
12041216
break;
12051217

1218+
case VIPS_FORMAT_DOUBLE:
12061219
case VIPS_FORMAT_DPCOMPLEX:
12071220
VCONV(double, double, double, CLIP_NONE);
12081221
break;

0 commit comments

Comments
 (0)