diff --git a/go.sum b/go.sum
index a66ef7c80e9ce13616c38f03c8b197295344a7ec..4e0fb494443f3f2a09847af1bc0f6c06171017b1 100644
--- a/go.sum
+++ b/go.sum
@@ -1,48 +1,39 @@
-github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/go-redis/redis v6.15.6+incompatible h1:H9evprGPLI8+ci7fxQx6WNZHJSb7be8FqJQRhdQZ5Sg=
-github.com/go-redis/redis v6.15.6+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
 github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
 github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
 github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
-github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
 github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
 github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -50,10 +41,9 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
@@ -66,18 +56,15 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/gographics/imagick.v2 v2.5.0 h1:3wOeg/IgtagJtveISUaX9A3F/L/5PxaFHkAz5AzgbgA=
-gopkg.in/gographics/imagick.v2 v2.5.0/go.mod h1:of4TbGX8yMcpgWkWFjha7FsOFr+NjOJ5O1qtKU27Yj0=
 gopkg.in/gographics/imagick.v2 v2.6.0 h1:ewRsUQk3QkjGumERlndbFn/kTYRjyMaPY5gxwpuAhik=
 gopkg.in/gographics/imagick.v2 v2.6.0/go.mod h1:/QVPLV/iKdNttRKthmDkeeGg+vdHurVEPc8zkU0XgBk=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/lib/colorspace.go b/lib/colorspace.go
new file mode 100644
index 0000000000000000000000000000000000000000..bfaaa965cf2abb33e35336ec4d08c58e27c6c7f0
--- /dev/null
+++ b/lib/colorspace.go
@@ -0,0 +1,5 @@
+package lib
+
+import "encoding/base64"
+
+var WorkingColorspace, _ = base64.StdEncoding.DecodeString("AAAEMGxjbXMEMAAAbW50clJHQiBYWVogB+AABQABAA0AGQABYWNzcCpuaXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1sY21zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMZGVzYwAAARQAAABGY3BydAAAAVwAAAE2d3RwdAAAApQAAAAUY2hhZAAAAqgAAAAsclhZWgAAAtQAAAAUYlhZWgAAAugAAAAUZ1hZWgAAAvwAAAAUclRSQwAAAxAAAAAQZ1RSQwAAAxAAAAAQYlRSQwAAAxAAAAAQY2hybQAAAyAAAAAkZG1uZAAAA0QAAADqbWx1YwAAAAAAAAABAAAADGVuVVMAAAAqAAAAHABBAEMARQBTAC0AZQBsAGwAZQAtAFYANAAtAGcAMQAwAC4AaQBjAGMAAAAAbWx1YwAAAAAAAAABAAAADGVuVVMAAAEaAAAAHABDAG8AcAB5AHIAaQBnAGgAdAAgADIAMAAxADYALAAgAEUAbABsAGUAIABTAHQAbwBuAGUAIAAoAGgAdAB0AHAAOgAvAC8AbgBpAG4AZQBkAGUAZwByAGUAZQBzAGIAZQBsAG8AdwAuAGMAbwBtAC8AKQAsACAAQwBDAC0AQgBZAC0AUwBBACAAMwAuADAAIABVAG4AcABvAHIAdABlAGQAIAAoAGgAdAB0AHAAcwA6AC8ALwBjAHIAZQBhAHQAaQB2AGUAYwBvAG0AbQBvAG4AcwAuAG8AcgBnAC8AbABpAGMAZQBuAHMAZQBzAC8AYgB5AC0AcwBhAC8AMwAuADAALwBsAGUAZwBhAGwAYwBvAGQAZQApAC4AAAAAWFlaIAAAAAAAAPbWAAEAAAAA0y1zZjMyAAAAAAABCL8AAARO///2aAAABYkAAP4D///8vv///jkAAALmAADQIlhZWiAAAAAAAAD9qwAAXKX///9OWFlaIAAAAAD///YJ///qZAAA0cJYWVogAAAAAAAAAyIAALj3AAACHXBhcmEAAAAAAAAAAAABAABjaHJtAAAAAAADAAAAALwWAABD6wAAAAAAAQAAAAAAB///7EltbHVjAAAAAAAAAAEAAAAMZW5VUwAAAM4AAAAcAEEAQwBFAFMAIABjAGgAcgBvAG0AYQB0AGkAYwBpAHQAaQBlAHMAIABmAHIAbwBtACAAVABCAC0AMgAwADEANAAtADAAMAA0ACwAIABoAHQAdABwADoALwAvAHcAdwB3AC4AbwBzAGMAYQByAHMALgBvAHIAZwAvAHMAYwBpAGUAbgBjAGUALQB0AGUAYwBoAG4AbwBsAG8AZwB5AC8AYQBjAGUAcwAvAGEAYwBlAHMALQBkAG8AYwB1AG0AZQBuAHQAYQB0AGkAbwBuAAAAAA==")
diff --git a/lib/processImageInstance.go b/lib/processImageInstance.go
new file mode 100644
index 0000000000000000000000000000000000000000..48e357f2b24497711530dd266842ae1813dd7c5b
--- /dev/null
+++ b/lib/processImageInstance.go
@@ -0,0 +1,55 @@
+package lib
+
+import (
+	"gopkg.in/gographics/imagick.v2/imagick"
+	"strings"
+)
+
+func ProcessImageInstance(
+	wand *imagick.MagickWand,
+	size Size,
+	quality Quality,
+	parameters ImageParameters,
+	target string,
+) error {
+	var err error
+	var mw *imagick.MagickWand
+
+	mw = wand.Clone()
+	defer mw.Destroy()
+
+	if err = ResizeImageInstance(mw, size); err != nil {
+		return err
+	}
+	for _, key := range mw.GetImageProperties("*") {
+		if !strings.HasPrefix(key, "png:") {
+			if err = mw.DeleteImageProperty(key); err != nil {
+				return err
+			}
+		}
+	}
+
+	if iccProfile, iccProfileOk := parameters.profiles["icc"]; iccProfileOk {
+		err = mw.ProfileImage("icc", iccProfile)
+	} else if iptcProfile, iptcProfileOk := parameters.profiles["iptc"]; iptcProfileOk {
+		err = mw.ProfileImage("iptc", iptcProfile)
+	} else {
+		err = mw.TransformImageColorspace(parameters.colorspace)
+	}
+
+	if err = mw.SetImageDepth(parameters.depth); err != nil {
+		return err
+	}
+
+	if quality.CompressionQuality != 0 {
+		_ = mw.SetImageCompressionQuality(quality.CompressionQuality)
+	}
+
+	if len(quality.SamplingFactors) != 0 {
+		_ = mw.SetSamplingFactors(quality.SamplingFactors)
+	}
+
+	err = mw.WriteImage(target)
+
+	return err
+}
diff --git a/lib/resizeImage.go b/lib/resizeImage.go
new file mode 100644
index 0000000000000000000000000000000000000000..4ef0d064122aa3672946a6dd2f81d4b2ca529127
--- /dev/null
+++ b/lib/resizeImage.go
@@ -0,0 +1,82 @@
+package lib
+
+import (
+	"fmt"
+	"gopkg.in/gographics/imagick.v2/imagick"
+	"path/filepath"
+)
+
+func goroutineWrapper(
+	errorChannel chan error,
+	wand *imagick.MagickWand,
+	config *Config, path string,
+	definition SizeDefinition,
+	parameters ImageParameters,
+) {
+	errorChannel <- ProcessImageInstance(
+		wand,
+		definition.Size,
+		config.Quality,
+		parameters,
+		path,
+	)
+}
+
+func ResizeImage(config *Config, imageId string) []error {
+	var err error
+	errorChannel := make(chan error)
+
+	wand := imagick.NewMagickWand()
+	defer wand.Destroy()
+
+	if err = wand.SetOption("png:include-chunk", "bKGD,cHRM,iCCP"); err != nil {
+		return []error{err}
+	}
+	if err = wand.SetOption("png:exclude-chunk", "EXIF,iTXt,tEXt,zTXt,date"); err != nil {
+		return []error{err}
+	}
+
+	if err = wand.ReadImage(filepath.Join(config.SourceFolder, imageId)); err != nil {
+		return []error{err}
+	}
+
+	_ = wand.AutoOrientImage()
+
+	colorSpace := wand.GetImageColorspace()
+	if colorSpace == imagick.COLORSPACE_UNDEFINED {
+		colorSpace = imagick.COLORSPACE_SRGB
+	}
+
+	profiles := map[string][]byte{}
+	for _, name := range wand.GetImageProfiles("*") {
+		profiles[name] = []byte(wand.GetImageProfile(name))
+	}
+
+	parameters := ImageParameters{
+		depth:      wand.GetImageDepth(),
+		profiles:   profiles,
+		colorspace: colorSpace,
+	}
+
+	if err = wand.SetImageDepth(16); err != nil {
+		panic(err)
+	}
+	if err = wand.ProfileImage("icc", WorkingColorspace); err != nil {
+		panic(err)
+	}
+
+	for _, definition := range config.Sizes {
+		path := filepath.Join(config.TargetFolder, fmt.Sprintf("%s%s", imageId, definition.Suffix))
+		go goroutineWrapper(errorChannel, wand, config, path, definition, parameters)
+	}
+
+	errors := make([]error, 0)
+	for i := 0; i < len(config.Sizes); i++ {
+		err := <-errorChannel
+		if err != nil {
+			errors = append(errors, err)
+		}
+	}
+
+	return errors
+}
diff --git a/util.go b/lib/resizeImageInstance.go
similarity index 64%
rename from util.go
rename to lib/resizeImageInstance.go
index a29342381966b864f1485fc8f1092216d30b648b..8cb0c534d517096bc894fdafe32155f13036669f 100644
--- a/util.go
+++ b/lib/resizeImageInstance.go
@@ -1,4 +1,4 @@
-package main
+package lib
 
 import (
 	"errors"
@@ -7,17 +7,9 @@ import (
 	"math"
 )
 
-func resize(wand *imagick.MagickWand, wandLinear *imagick.MagickWand, originalColorSpace imagick.ColorspaceType, profiles map[string]string, size Size, quality Quality, target string) error {
+func ResizeImageInstance(mw *imagick.MagickWand, size Size) error {
 	var err error
-	var mw *imagick.MagickWand
-
-	if size.Width == 0 && size.Height == 0 {
-		mw = wand.Clone()
-		defer mw.Destroy()
-	} else {
-		mw = wandLinear.Clone()
-		defer mw.Destroy()
-
+	if size.Width != 0 || size.Height != 0 {
 		width := mw.GetImageWidth()
 		height := mw.GetImageHeight()
 
@@ -47,8 +39,7 @@ func resize(wand *imagick.MagickWand, wandLinear *imagick.MagickWand, originalCo
 				dx := int((width - cWidth) / 2)
 				dy := int((height - cHeight) / 2)
 
-				err = mw.CropImage(cWidth, cHeight, dx, dy)
-				if err != nil {
+				if err = mw.CropImage(cWidth, cHeight, dx, dy); err != nil {
 					return err
 				}
 
@@ -69,33 +60,11 @@ func resize(wand *imagick.MagickWand, wandLinear *imagick.MagickWand, originalCo
 		}
 
 		if (width != nWidth) || (height != nHeight) {
-			err = mw.ResizeImage(nWidth, nHeight, imagick.FILTER_BOX, 1)
-			if err != nil {
+			if err = mw.ResizeImage(nWidth, nHeight, imagick.FILTER_BOX, 1); err != nil {
 				return err
 			}
 		}
 	}
 
-	err = mw.TransformImageColorspace(originalColorSpace)
-	if err != nil {
-		return err
-	}
-
-	if quality.CompressionQuality != 0 {
-		_ = mw.SetImageCompressionQuality(quality.CompressionQuality)
-	}
-
-	if len(quality.SamplingFactors) != 0 {
-		_ = mw.SetSamplingFactors(quality.SamplingFactors)
-	}
-
-	_ = mw.StripImage()
-
-	for key, value := range profiles {
-		_ = mw.SetImageProfile(key, []byte(value))
-	}
-
-	err = mw.WriteImage(target)
-
-	return err
+	return nil
 }
diff --git a/types.go b/lib/types.go
similarity index 84%
rename from types.go
rename to lib/types.go
index 2ea713f939eb5193892cb27f757bfac973f9a7ea..c3a37baed059206cd76b15d570dd9e5ae4375940 100644
--- a/types.go
+++ b/lib/types.go
@@ -1,7 +1,8 @@
-package main
+package lib
 
 import (
 	"encoding/json"
+	"gopkg.in/gographics/imagick.v2/imagick"
 	"os"
 	"time"
 )
@@ -15,6 +16,12 @@ type Image struct {
 	MimeType     string `json:"mime_type"`
 }
 
+type ImageParameters struct {
+	profiles   map[string][]byte
+	colorspace imagick.ColorspaceType
+	depth      uint
+}
+
 type Result struct {
 	Id      string   `json:"id"`
 	Success bool     `json:"success"`
@@ -66,8 +73,8 @@ type Config struct {
 func NewConfigFromEnv() Config {
 	config := Config{}
 
-	json.Unmarshal([]byte(os.Getenv("IK8R_SIZES")), &config.Sizes)
-	json.Unmarshal([]byte(os.Getenv("IK8R_QUALITY")), &config.Quality)
+	_ = json.Unmarshal([]byte(os.Getenv("IK8R_SIZES")), &config.Sizes)
+	_ = json.Unmarshal([]byte(os.Getenv("IK8R_QUALITY")), &config.Quality)
 	config.SourceFolder = os.Getenv("IK8R_SOURCE_FOLDER")
 	config.TargetFolder = os.Getenv("IK8R_TARGET_FOLDER")
 	config.Redis.Address = os.Getenv("IK8R_REDIS_ADDRESS")
diff --git a/main.go b/main.go
index 2d9f849548365262f646311701e0a26ca6a3ee16..ebd92cdbb057d0acea2e1b2d7894136c04ce2be6 100644
--- a/main.go
+++ b/main.go
@@ -3,6 +3,7 @@ package main
 import (
 	"encoding/json"
 	"fmt"
+	"git.kuschku.de/justjanne/imghost/lib"
 	"github.com/go-redis/redis"
 	"gopkg.in/gographics/imagick.v2/imagick"
 	"net/http"
@@ -11,7 +12,7 @@ import (
 	"time"
 )
 
-func returnResult(config *Config, client *redis.Client, result Result) {
+func returnResult(config *lib.Config, client *redis.Client, result lib.Result) {
 	raw, err := json.Marshal(result)
 	if err != nil {
 		panic(err)
@@ -19,79 +20,31 @@ func returnResult(config *Config, client *redis.Client, result Result) {
 	client.Publish(config.ResultChannel, string(raw))
 }
 
-func generateSize(errorChannel chan error, wand *imagick.MagickWand, wandLinear *imagick.MagickWand, colorSpace imagick.ColorspaceType, profiles map[string]string, config *Config, image Image, definition SizeDefinition) {
-	errorChannel <- resize(
-		wand,
-		wandLinear,
-		colorSpace,
-		profiles,
-		definition.Size,
-		config.Quality,
-		filepath.Join(config.TargetFolder, fmt.Sprintf("%s%s", image.Id, definition.Suffix)),
-	)
-}
-
-func processImage(config *Config, client *redis.Client, value string) {
-	image := Image{}
+func processImage(config *lib.Config, client *redis.Client, value string) {
+	image := lib.Image{}
 	if err := json.Unmarshal([]byte(value), &image); err != nil {
 		panic(err)
 	}
 	fmt.Printf("Received task %s at %d\n", image.Id, time.Now().Unix())
 
-	errorChannel := make(chan error)
-
-	wand := imagick.NewMagickWand()
-	defer wand.Destroy()
-
-	err := wand.ReadImage(filepath.Join(config.SourceFolder, image.Id))
-	if err != nil {
-		panic(err)
-	}
-
-	_ = wand.AutoOrientImage()
-
-	wandLinear := wand.Clone()
-	defer wandLinear.Destroy()
-
-	colorSpace := wand.GetImageColorspace()
-	if colorSpace == imagick.COLORSPACE_UNDEFINED {
-		colorSpace = imagick.COLORSPACE_SRGB
-	}
-
-	profiles := map[string]string{}
-	for _, name := range wand.GetImageProfiles("*") {
-		profiles[name] = wand.GetImageProfile(name)
-	}
-
-	err = wandLinear.TransformImageColorspace(imagick.COLORSPACE_LAB)
-	if err != nil {
-		panic(err)
-	}
+	errors := lib.ResizeImage(config, image.Id)
+	_ = os.Remove(filepath.Join(config.SourceFolder, image.Id))
 
-	for _, definition := range config.Sizes {
-		go generateSize(errorChannel, wand, wandLinear, colorSpace, profiles, config, image, definition)
+	errorMessages := make([]string, len(errors))
+	for i, err := range errors {
+		errorMessages[i] = err.Error()
 	}
 
-	errors := make([]string, 0)
-	for i := 0; i < len(config.Sizes); i++ {
-		err := <-errorChannel
-		if err != nil {
-			errors = append(errors, err.Error())
-		}
-	}
-
-	os.Remove(filepath.Join(config.SourceFolder, image.Id))
-
 	fmt.Printf("Finished task %s at %d\n", image.Id, time.Now().Unix())
 
 	if len(errors) != 0 {
-		returnResult(config, client, Result{
+		returnResult(config, client, lib.Result{
 			Id:      image.Id,
 			Success: false,
-			Errors:  errors,
+			Errors:  errorMessages,
 		})
 	} else {
-		returnResult(config, client, Result{
+		returnResult(config, client, lib.Result{
 			Id:      image.Id,
 			Success: true,
 		})
@@ -100,7 +53,7 @@ func processImage(config *Config, client *redis.Client, value string) {
 
 func main() {
 	go func() {
-		config := NewConfigFromEnv()
+		config := lib.NewConfigFromEnv()
 
 		imagick.Initialize()
 		defer imagick.Terminate()
@@ -120,11 +73,10 @@ func main() {
 	}()
 
 	http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
-		w.Write([]byte("OK"))
+		_, _ = w.Write([]byte("OK"))
 	})
 
-	err := http.ListenAndServe(":8080", nil)
-	if err != nil {
+	if err := http.ListenAndServe(":8080", nil); err != nil {
 		panic(err)
 	}
 }