processing_test.go 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. package processing
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "testing"
  8. "github.com/stretchr/testify/suite"
  9. "github.com/imgproxy/imgproxy/v3/fetcher"
  10. "github.com/imgproxy/imgproxy/v3/ierrors"
  11. "github.com/imgproxy/imgproxy/v3/imagedata"
  12. "github.com/imgproxy/imgproxy/v3/logger"
  13. "github.com/imgproxy/imgproxy/v3/options"
  14. "github.com/imgproxy/imgproxy/v3/security"
  15. "github.com/imgproxy/imgproxy/v3/testutil"
  16. "github.com/imgproxy/imgproxy/v3/vips"
  17. )
  18. type ProcessingTestSuite struct {
  19. testutil.LazySuite
  20. imageDataFactory testutil.LazyObj[*imagedata.Factory]
  21. securityConfig testutil.LazyObj[*security.Config]
  22. security testutil.LazyObj[*security.Checker]
  23. poConfig testutil.LazyObj[*options.Config]
  24. po testutil.LazyObj[*options.Factory]
  25. config testutil.LazyObj[*Config]
  26. processor testutil.LazyObj[*Processor]
  27. }
  28. func (s *ProcessingTestSuite) SetupSuite() {
  29. s.Require().NoError(vips.Init())
  30. logger.Mute()
  31. s.imageDataFactory, _ = testutil.NewLazySuiteObj(s, func() (*imagedata.Factory, error) {
  32. c := fetcher.NewDefaultConfig()
  33. f, err := fetcher.New(&c)
  34. if err != nil {
  35. return nil, err
  36. }
  37. return imagedata.NewFactory(f), nil
  38. })
  39. s.securityConfig, _ = testutil.NewLazySuiteObj(s, func() (*security.Config, error) {
  40. c := security.NewDefaultConfig()
  41. c.DefaultOptions.MaxSrcResolution = 10 * 1024 * 1024
  42. c.DefaultOptions.MaxSrcFileSize = 10 * 1024 * 1024
  43. c.DefaultOptions.MaxAnimationFrames = 100
  44. c.DefaultOptions.MaxAnimationFrameResolution = 10 * 1024 * 1024
  45. return &c, nil
  46. })
  47. s.security, _ = testutil.NewLazySuiteObj(s, func() (*security.Checker, error) {
  48. return security.New(s.securityConfig())
  49. })
  50. s.poConfig, _ = testutil.NewLazySuiteObj(s, func() (*options.Config, error) {
  51. c := options.NewDefaultConfig()
  52. return &c, nil
  53. })
  54. s.po, _ = testutil.NewLazySuiteObj(s, func() (*options.Factory, error) {
  55. return options.NewFactory(s.poConfig(), s.security())
  56. })
  57. s.config, _ = testutil.NewLazySuiteObj(s, func() (*Config, error) {
  58. c := NewDefaultConfig()
  59. return &c, nil
  60. })
  61. s.processor, _ = testutil.NewLazySuiteObj(s, func() (*Processor, error) {
  62. return New(s.config(), nil)
  63. })
  64. }
  65. func (s *ProcessingTestSuite) TearDownSuite() {
  66. logger.Unmute()
  67. }
  68. func (s *ProcessingTestSuite) openFile(name string) imagedata.ImageData {
  69. wd, err := os.Getwd()
  70. s.Require().NoError(err)
  71. path := filepath.Join(wd, "..", "testdata", name)
  72. imagedata, err := s.imageDataFactory().NewFromPath(path)
  73. s.Require().NoError(err)
  74. return imagedata
  75. }
  76. func (s *ProcessingTestSuite) checkSize(r *Result, width, height int) {
  77. s.Require().NotNil(r)
  78. s.Require().Equal(width, r.ResultWidth, "Width mismatch")
  79. s.Require().Equal(height, r.ResultHeight, "Height mismatch")
  80. }
  81. func (s *ProcessingTestSuite) processImageAndCheck(imgdata imagedata.ImageData, po *options.ProcessingOptions, expectedWidth, expectedHeight int) {
  82. result, err := s.processor().ProcessImage(context.Background(), imgdata, po, nil)
  83. s.Require().NoError(err)
  84. s.Require().NotNil(result)
  85. s.checkSize(result, expectedWidth, expectedHeight)
  86. }
  87. func (s *ProcessingTestSuite) TestResizeToFit() {
  88. imgdata := s.openFile("test2.jpg")
  89. po := s.po().NewProcessingOptions()
  90. po.ResizingType = options.ResizeFit
  91. testCases := []struct {
  92. width int
  93. height int
  94. outWidth int
  95. outHeight int
  96. }{
  97. {width: 50, height: 50, outWidth: 50, outHeight: 25},
  98. {width: 50, height: 20, outWidth: 40, outHeight: 20},
  99. {width: 20, height: 50, outWidth: 20, outHeight: 10},
  100. {width: 300, height: 300, outWidth: 200, outHeight: 100},
  101. {width: 300, height: 50, outWidth: 100, outHeight: 50},
  102. {width: 100, height: 300, outWidth: 100, outHeight: 50},
  103. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  104. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  105. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  106. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  107. }
  108. for _, tc := range testCases {
  109. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  110. po.Width = tc.width
  111. po.Height = tc.height
  112. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  113. })
  114. }
  115. }
  116. func (s *ProcessingTestSuite) TestResizeToFitEnlarge() {
  117. imgdata := s.openFile("test2.jpg")
  118. po := s.po().NewProcessingOptions()
  119. po.ResizingType = options.ResizeFit
  120. po.Enlarge = true
  121. testCases := []struct {
  122. width int
  123. height int
  124. outWidth int
  125. outHeight int
  126. }{
  127. {width: 50, height: 50, outWidth: 50, outHeight: 25},
  128. {width: 50, height: 20, outWidth: 40, outHeight: 20},
  129. {width: 20, height: 50, outWidth: 20, outHeight: 10},
  130. {width: 300, height: 300, outWidth: 300, outHeight: 150},
  131. {width: 300, height: 125, outWidth: 250, outHeight: 125},
  132. {width: 250, height: 300, outWidth: 250, outHeight: 125},
  133. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  134. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  135. {width: 0, height: 200, outWidth: 400, outHeight: 200},
  136. {width: 300, height: 0, outWidth: 300, outHeight: 150},
  137. }
  138. for _, tc := range testCases {
  139. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  140. po.Width = tc.width
  141. po.Height = tc.height
  142. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  143. })
  144. }
  145. }
  146. func (s *ProcessingTestSuite) TestResizeToFitExtend() {
  147. imgdata := s.openFile("test2.jpg")
  148. po := s.po().NewProcessingOptions()
  149. po.ResizingType = options.ResizeFit
  150. po.Extend = options.ExtendOptions{
  151. Enabled: true,
  152. Gravity: options.GravityOptions{
  153. Type: options.GravityCenter,
  154. },
  155. }
  156. testCases := []struct {
  157. width int
  158. height int
  159. outWidth int
  160. outHeight int
  161. }{
  162. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  163. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  164. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  165. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  166. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  167. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  168. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  169. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  170. {width: 0, height: 200, outWidth: 200, outHeight: 200},
  171. {width: 300, height: 0, outWidth: 300, outHeight: 100},
  172. }
  173. for _, tc := range testCases {
  174. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  175. po.Width = tc.width
  176. po.Height = tc.height
  177. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  178. })
  179. }
  180. }
  181. func (s *ProcessingTestSuite) TestResizeToFitExtendAR() {
  182. imgdata := s.openFile("test2.jpg")
  183. po := s.po().NewProcessingOptions()
  184. po.ResizingType = options.ResizeFit
  185. po.ExtendAspectRatio = options.ExtendOptions{
  186. Enabled: true,
  187. Gravity: options.GravityOptions{
  188. Type: options.GravityCenter,
  189. },
  190. }
  191. testCases := []struct {
  192. width int
  193. height int
  194. outWidth int
  195. outHeight int
  196. }{
  197. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  198. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  199. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  200. {width: 300, height: 300, outWidth: 200, outHeight: 200},
  201. {width: 300, height: 125, outWidth: 240, outHeight: 100},
  202. {width: 250, height: 500, outWidth: 200, outHeight: 400},
  203. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  204. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  205. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  206. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  207. }
  208. for _, tc := range testCases {
  209. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  210. po.Width = tc.width
  211. po.Height = tc.height
  212. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  213. })
  214. }
  215. }
  216. func (s *ProcessingTestSuite) TestResizeToFill() {
  217. imgdata := s.openFile("test2.jpg")
  218. po := s.po().NewProcessingOptions()
  219. po.ResizingType = options.ResizeFill
  220. testCases := []struct {
  221. width int
  222. height int
  223. outWidth int
  224. outHeight int
  225. }{
  226. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  227. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  228. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  229. {width: 300, height: 300, outWidth: 200, outHeight: 100},
  230. {width: 300, height: 50, outWidth: 200, outHeight: 50},
  231. {width: 100, height: 300, outWidth: 100, outHeight: 100},
  232. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  233. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  234. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  235. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  236. }
  237. for _, tc := range testCases {
  238. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  239. po.Width = tc.width
  240. po.Height = tc.height
  241. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  242. })
  243. }
  244. }
  245. func (s *ProcessingTestSuite) TestResizeToFillEnlarge() {
  246. imgdata := s.openFile("test2.jpg")
  247. po := s.po().NewProcessingOptions()
  248. po.ResizingType = options.ResizeFill
  249. po.Enlarge = true
  250. testCases := []struct {
  251. width int
  252. height int
  253. outWidth int
  254. outHeight int
  255. }{
  256. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  257. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  258. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  259. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  260. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  261. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  262. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  263. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  264. {width: 0, height: 200, outWidth: 400, outHeight: 200},
  265. {width: 300, height: 0, outWidth: 300, outHeight: 150},
  266. }
  267. for _, tc := range testCases {
  268. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  269. po.Width = tc.width
  270. po.Height = tc.height
  271. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  272. })
  273. }
  274. }
  275. func (s *ProcessingTestSuite) TestResizeToFillExtend() {
  276. imgdata := s.openFile("test2.jpg")
  277. po := s.po().NewProcessingOptions()
  278. po.ResizingType = options.ResizeFill
  279. po.Extend = options.ExtendOptions{
  280. Enabled: true,
  281. Gravity: options.GravityOptions{
  282. Type: options.GravityCenter,
  283. },
  284. }
  285. testCases := []struct {
  286. width int
  287. height int
  288. outWidth int
  289. outHeight int
  290. }{
  291. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  292. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  293. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  294. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  295. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  296. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  297. {width: 300, height: 50, outWidth: 300, outHeight: 50},
  298. {width: 100, height: 300, outWidth: 100, outHeight: 300},
  299. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  300. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  301. {width: 0, height: 200, outWidth: 200, outHeight: 200},
  302. {width: 300, height: 0, outWidth: 300, outHeight: 100},
  303. }
  304. for _, tc := range testCases {
  305. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  306. po.Width = tc.width
  307. po.Height = tc.height
  308. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  309. })
  310. }
  311. }
  312. func (s *ProcessingTestSuite) TestResizeToFillExtendAR() {
  313. imgdata := s.openFile("test2.jpg")
  314. po := s.po().NewProcessingOptions()
  315. po.ResizingType = options.ResizeFill
  316. po.ExtendAspectRatio = options.ExtendOptions{
  317. Enabled: true,
  318. Gravity: options.GravityOptions{
  319. Type: options.GravityCenter,
  320. },
  321. }
  322. testCases := []struct {
  323. width int
  324. height int
  325. outWidth int
  326. outHeight int
  327. }{
  328. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  329. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  330. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  331. {width: 300, height: 300, outWidth: 200, outHeight: 200},
  332. {width: 300, height: 125, outWidth: 240, outHeight: 100},
  333. {width: 250, height: 500, outWidth: 200, outHeight: 400},
  334. {width: 300, height: 50, outWidth: 300, outHeight: 50},
  335. {width: 100, height: 300, outWidth: 100, outHeight: 300},
  336. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  337. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  338. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  339. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  340. }
  341. for _, tc := range testCases {
  342. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  343. po.Width = tc.width
  344. po.Height = tc.height
  345. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  346. })
  347. }
  348. }
  349. func (s *ProcessingTestSuite) TestResizeToFillDown() {
  350. imgdata := s.openFile("test2.jpg")
  351. po := s.po().NewProcessingOptions()
  352. po.ResizingType = options.ResizeFillDown
  353. testCases := []struct {
  354. width int
  355. height int
  356. outWidth int
  357. outHeight int
  358. }{
  359. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  360. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  361. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  362. {width: 300, height: 300, outWidth: 100, outHeight: 100},
  363. {width: 300, height: 125, outWidth: 200, outHeight: 83},
  364. {width: 250, height: 300, outWidth: 83, outHeight: 100},
  365. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  366. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  367. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  368. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  369. }
  370. for _, tc := range testCases {
  371. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  372. po.Width = tc.width
  373. po.Height = tc.height
  374. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  375. })
  376. }
  377. }
  378. func (s *ProcessingTestSuite) TestResizeToFillDownEnlarge() {
  379. imgdata := s.openFile("test2.jpg")
  380. po := s.po().NewProcessingOptions()
  381. po.ResizingType = options.ResizeFillDown
  382. po.Enlarge = true
  383. testCases := []struct {
  384. width int
  385. height int
  386. outWidth int
  387. outHeight int
  388. }{
  389. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  390. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  391. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  392. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  393. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  394. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  395. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  396. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  397. {width: 0, height: 200, outWidth: 400, outHeight: 200},
  398. {width: 300, height: 0, outWidth: 300, outHeight: 150},
  399. }
  400. for _, tc := range testCases {
  401. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  402. po.Width = tc.width
  403. po.Height = tc.height
  404. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  405. })
  406. }
  407. }
  408. func (s *ProcessingTestSuite) TestResizeToFillDownExtend() {
  409. imgdata := s.openFile("test2.jpg")
  410. po := s.po().NewProcessingOptions()
  411. po.ResizingType = options.ResizeFillDown
  412. po.Extend = options.ExtendOptions{
  413. Enabled: true,
  414. Gravity: options.GravityOptions{
  415. Type: options.GravityCenter,
  416. },
  417. }
  418. testCases := []struct {
  419. width int
  420. height int
  421. outWidth int
  422. outHeight int
  423. }{
  424. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  425. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  426. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  427. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  428. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  429. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  430. {width: 300, height: 50, outWidth: 300, outHeight: 50},
  431. {width: 100, height: 300, outWidth: 100, outHeight: 300},
  432. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  433. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  434. {width: 0, height: 200, outWidth: 200, outHeight: 200},
  435. {width: 300, height: 0, outWidth: 300, outHeight: 100},
  436. }
  437. for _, tc := range testCases {
  438. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  439. po.Width = tc.width
  440. po.Height = tc.height
  441. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  442. })
  443. }
  444. }
  445. func (s *ProcessingTestSuite) TestResizeToFillDownExtendAR() {
  446. imgdata := s.openFile("test2.jpg")
  447. po := s.po().NewProcessingOptions()
  448. po.ResizingType = options.ResizeFillDown
  449. po.ExtendAspectRatio = options.ExtendOptions{
  450. Enabled: true,
  451. Gravity: options.GravityOptions{
  452. Type: options.GravityCenter,
  453. },
  454. }
  455. testCases := []struct {
  456. width int
  457. height int
  458. outWidth int
  459. outHeight int
  460. }{
  461. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  462. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  463. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  464. {width: 300, height: 300, outWidth: 100, outHeight: 100},
  465. {width: 300, height: 125, outWidth: 200, outHeight: 83},
  466. {width: 250, height: 300, outWidth: 83, outHeight: 100},
  467. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  468. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  469. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  470. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  471. }
  472. for _, tc := range testCases {
  473. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  474. po.Width = tc.width
  475. po.Height = tc.height
  476. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  477. })
  478. }
  479. }
  480. func (s *ProcessingTestSuite) TestResultSizeLimit() {
  481. imgdata := s.openFile("test2.jpg")
  482. po := s.po().NewProcessingOptions()
  483. testCases := []struct {
  484. limit int
  485. width int
  486. height int
  487. resizingType options.ResizeType
  488. enlarge bool
  489. extend bool
  490. extendAR bool
  491. padding options.PaddingOptions
  492. rotate int
  493. outWidth int
  494. outHeight int
  495. }{
  496. {
  497. limit: 1000,
  498. width: 100,
  499. height: 100,
  500. resizingType: options.ResizeFit,
  501. outWidth: 100,
  502. outHeight: 50,
  503. },
  504. {
  505. limit: 50,
  506. width: 100,
  507. height: 100,
  508. resizingType: options.ResizeFit,
  509. outWidth: 50,
  510. outHeight: 25,
  511. },
  512. {
  513. limit: 50,
  514. width: 0,
  515. height: 0,
  516. resizingType: options.ResizeFit,
  517. outWidth: 50,
  518. outHeight: 25,
  519. },
  520. {
  521. limit: 100,
  522. width: 0,
  523. height: 100,
  524. resizingType: options.ResizeFit,
  525. outWidth: 100,
  526. outHeight: 50,
  527. },
  528. {
  529. limit: 50,
  530. width: 150,
  531. height: 0,
  532. resizingType: options.ResizeFit,
  533. outWidth: 50,
  534. outHeight: 25,
  535. },
  536. {
  537. limit: 100,
  538. width: 1000,
  539. height: 1000,
  540. resizingType: options.ResizeFit,
  541. outWidth: 100,
  542. outHeight: 50,
  543. },
  544. {
  545. limit: 100,
  546. width: 1000,
  547. height: 1000,
  548. resizingType: options.ResizeFit,
  549. enlarge: true,
  550. outWidth: 100,
  551. outHeight: 50,
  552. },
  553. {
  554. limit: 100,
  555. width: 1000,
  556. height: 2000,
  557. resizingType: options.ResizeFit,
  558. extend: true,
  559. outWidth: 50,
  560. outHeight: 100,
  561. },
  562. {
  563. limit: 100,
  564. width: 1000,
  565. height: 2000,
  566. resizingType: options.ResizeFit,
  567. extendAR: true,
  568. outWidth: 50,
  569. outHeight: 100,
  570. },
  571. {
  572. limit: 100,
  573. width: 100,
  574. height: 150,
  575. resizingType: options.ResizeFit,
  576. rotate: 90,
  577. outWidth: 50,
  578. outHeight: 100,
  579. },
  580. {
  581. limit: 100,
  582. width: 0,
  583. height: 0,
  584. resizingType: options.ResizeFit,
  585. rotate: 90,
  586. outWidth: 50,
  587. outHeight: 100,
  588. },
  589. {
  590. limit: 200,
  591. width: 100,
  592. height: 100,
  593. resizingType: options.ResizeFit,
  594. padding: options.PaddingOptions{
  595. Enabled: true,
  596. Top: 100,
  597. Right: 200,
  598. Bottom: 300,
  599. Left: 400,
  600. },
  601. outWidth: 200,
  602. outHeight: 129,
  603. },
  604. {
  605. limit: 1000,
  606. width: 100,
  607. height: 100,
  608. resizingType: options.ResizeFill,
  609. outWidth: 100,
  610. outHeight: 100,
  611. },
  612. {
  613. limit: 50,
  614. width: 100,
  615. height: 100,
  616. resizingType: options.ResizeFill,
  617. outWidth: 50,
  618. outHeight: 50,
  619. },
  620. {
  621. limit: 50,
  622. width: 1000,
  623. height: 50,
  624. resizingType: options.ResizeFill,
  625. outWidth: 50,
  626. outHeight: 13,
  627. },
  628. {
  629. limit: 50,
  630. width: 100,
  631. height: 1000,
  632. resizingType: options.ResizeFill,
  633. outWidth: 50,
  634. outHeight: 50,
  635. },
  636. {
  637. limit: 50,
  638. width: 0,
  639. height: 0,
  640. resizingType: options.ResizeFill,
  641. outWidth: 50,
  642. outHeight: 25,
  643. },
  644. {
  645. limit: 100,
  646. width: 0,
  647. height: 100,
  648. resizingType: options.ResizeFill,
  649. outWidth: 100,
  650. outHeight: 50,
  651. },
  652. {
  653. limit: 50,
  654. width: 150,
  655. height: 0,
  656. resizingType: options.ResizeFill,
  657. outWidth: 50,
  658. outHeight: 25,
  659. },
  660. {
  661. limit: 100,
  662. width: 1000,
  663. height: 1000,
  664. resizingType: options.ResizeFill,
  665. outWidth: 100,
  666. outHeight: 50,
  667. },
  668. {
  669. limit: 100,
  670. width: 1000,
  671. height: 1000,
  672. resizingType: options.ResizeFill,
  673. enlarge: true,
  674. outWidth: 100,
  675. outHeight: 100,
  676. },
  677. {
  678. limit: 100,
  679. width: 1000,
  680. height: 2000,
  681. resizingType: options.ResizeFill,
  682. extend: true,
  683. outWidth: 50,
  684. outHeight: 100,
  685. },
  686. {
  687. limit: 100,
  688. width: 1000,
  689. height: 2000,
  690. resizingType: options.ResizeFill,
  691. extendAR: true,
  692. outWidth: 50,
  693. outHeight: 100,
  694. },
  695. {
  696. limit: 100,
  697. width: 100,
  698. height: 150,
  699. resizingType: options.ResizeFill,
  700. rotate: 90,
  701. outWidth: 67,
  702. outHeight: 100,
  703. },
  704. {
  705. limit: 100,
  706. width: 0,
  707. height: 0,
  708. resizingType: options.ResizeFill,
  709. rotate: 90,
  710. outWidth: 50,
  711. outHeight: 100,
  712. },
  713. {
  714. limit: 200,
  715. width: 100,
  716. height: 100,
  717. resizingType: options.ResizeFill,
  718. padding: options.PaddingOptions{
  719. Enabled: true,
  720. Top: 100,
  721. Right: 200,
  722. Bottom: 300,
  723. Left: 400,
  724. },
  725. outWidth: 200,
  726. outHeight: 144,
  727. },
  728. {
  729. limit: 1000,
  730. width: 100,
  731. height: 100,
  732. resizingType: options.ResizeFillDown,
  733. outWidth: 100,
  734. outHeight: 100,
  735. },
  736. {
  737. limit: 50,
  738. width: 100,
  739. height: 100,
  740. resizingType: options.ResizeFillDown,
  741. outWidth: 50,
  742. outHeight: 50,
  743. },
  744. {
  745. limit: 50,
  746. width: 1000,
  747. height: 50,
  748. resizingType: options.ResizeFillDown,
  749. outWidth: 50,
  750. outHeight: 3,
  751. },
  752. {
  753. limit: 50,
  754. width: 100,
  755. height: 1000,
  756. resizingType: options.ResizeFillDown,
  757. outWidth: 5,
  758. outHeight: 50,
  759. },
  760. {
  761. limit: 50,
  762. width: 0,
  763. height: 0,
  764. resizingType: options.ResizeFillDown,
  765. outWidth: 50,
  766. outHeight: 25,
  767. },
  768. {
  769. limit: 100,
  770. width: 0,
  771. height: 100,
  772. resizingType: options.ResizeFillDown,
  773. outWidth: 100,
  774. outHeight: 50,
  775. },
  776. {
  777. limit: 50,
  778. width: 150,
  779. height: 0,
  780. resizingType: options.ResizeFillDown,
  781. outWidth: 50,
  782. outHeight: 25,
  783. },
  784. {
  785. limit: 100,
  786. width: 1000,
  787. height: 1000,
  788. resizingType: options.ResizeFillDown,
  789. outWidth: 100,
  790. outHeight: 100,
  791. },
  792. {
  793. limit: 100,
  794. width: 1000,
  795. height: 1000,
  796. resizingType: options.ResizeFillDown,
  797. enlarge: true,
  798. outWidth: 100,
  799. outHeight: 100,
  800. },
  801. {
  802. limit: 100,
  803. width: 1000,
  804. height: 2000,
  805. resizingType: options.ResizeFillDown,
  806. extend: true,
  807. outWidth: 50,
  808. outHeight: 100,
  809. },
  810. {
  811. limit: 100,
  812. width: 1000,
  813. height: 2000,
  814. resizingType: options.ResizeFillDown,
  815. extendAR: true,
  816. outWidth: 50,
  817. outHeight: 100,
  818. },
  819. {
  820. limit: 100,
  821. width: 1000,
  822. height: 1500,
  823. resizingType: options.ResizeFillDown,
  824. rotate: 90,
  825. outWidth: 67,
  826. outHeight: 100,
  827. },
  828. {
  829. limit: 100,
  830. width: 0,
  831. height: 0,
  832. resizingType: options.ResizeFillDown,
  833. rotate: 90,
  834. outWidth: 50,
  835. outHeight: 100,
  836. },
  837. {
  838. limit: 200,
  839. width: 100,
  840. height: 100,
  841. resizingType: options.ResizeFillDown,
  842. padding: options.PaddingOptions{
  843. Enabled: true,
  844. Top: 100,
  845. Right: 200,
  846. Bottom: 300,
  847. Left: 400,
  848. },
  849. outWidth: 200,
  850. outHeight: 144,
  851. },
  852. {
  853. limit: 200,
  854. width: 1000,
  855. height: 1000,
  856. resizingType: options.ResizeFillDown,
  857. padding: options.PaddingOptions{
  858. Enabled: true,
  859. Top: 100,
  860. Right: 200,
  861. Bottom: 300,
  862. Left: 400,
  863. },
  864. outWidth: 200,
  865. outHeight: 144,
  866. },
  867. }
  868. for _, tc := range testCases {
  869. name := fmt.Sprintf("%s_%dx%d_limit_%d", tc.resizingType, tc.width, tc.height, tc.limit)
  870. if tc.enlarge {
  871. name += "_enlarge"
  872. }
  873. if tc.extend {
  874. name += "_extend"
  875. }
  876. if tc.extendAR {
  877. name += "_extendAR"
  878. }
  879. if tc.rotate != 0 {
  880. name += fmt.Sprintf("_rot_%d", tc.rotate)
  881. }
  882. if tc.padding.Enabled {
  883. name += fmt.Sprintf("_padding_%dx%dx%dx%d", tc.padding.Top, tc.padding.Right, tc.padding.Bottom, tc.padding.Left)
  884. }
  885. s.Run(name, func() {
  886. po.SecurityOptions.MaxResultDimension = tc.limit
  887. po.Width = tc.width
  888. po.Height = tc.height
  889. po.ResizingType = tc.resizingType
  890. po.Enlarge = tc.enlarge
  891. po.Extend.Enabled = tc.extend
  892. po.ExtendAspectRatio.Enabled = tc.extendAR
  893. po.Rotate = tc.rotate
  894. po.Padding = tc.padding
  895. s.processImageAndCheck(imgdata, po, tc.outWidth, tc.outHeight)
  896. })
  897. }
  898. }
  899. func (s *ProcessingTestSuite) TestImageResolutionTooLarge() {
  900. po := s.po().NewProcessingOptions()
  901. po.SecurityOptions.MaxSrcResolution = 1
  902. imgdata := s.openFile("test2.jpg")
  903. _, err := s.processor().ProcessImage(context.Background(), imgdata, po, nil)
  904. s.Require().Error(err)
  905. s.Require().Equal(422, ierrors.Wrap(err, 0).StatusCode())
  906. }
  907. func TestProcessing(t *testing.T) {
  908. suite.Run(t, new(ProcessingTestSuite))
  909. }