mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-25 17:53:56 +01:00
chore (maintenance): deprecate old thumbnail plugin
This commit is contained in:
parent
63ae5f2ed8
commit
f4fe61c512
48 changed files with 0 additions and 1072 deletions
|
|
@ -1,38 +0,0 @@
|
|||
PLATFORM=linux
|
||||
ARCH=amd64
|
||||
|
||||
all:
|
||||
@make jpeg
|
||||
@make png
|
||||
@make raw
|
||||
|
||||
image_jpeg.o:
|
||||
gcc -Wall -c src/image_jpeg.c -o src/image_jpeg.o
|
||||
|
||||
image_png.o:
|
||||
gcc -Wall -c src/image_png.c -o src/image_png.o
|
||||
|
||||
image_raw.o:
|
||||
gcc -Wall -c src/image_raw.c -o src/image_raw.o
|
||||
|
||||
jpeg: image_jpeg.o
|
||||
gcc -static src/main_jpeg_to_jpeg.c src/image_jpeg.o -o dist/jpeg_$(PLATFORM)_$(ARCH).bin -l:libjpeg.a
|
||||
sha256sum ./dist/jpeg_$(PLATFORM)_$(ARCH).bin | awk '{ printf $$1 }' > dist/jpeg_$(PLATFORM)_$(ARCH).bin.sha256
|
||||
|
||||
png: image_png.o
|
||||
gcc -static -Wall src/main_png_to_webp.c src/image_png.o -o dist/png_$(PLATFORM)_$(ARCH).bin -l:libpng.a -l:libz.a -l:libwebp.a -lpthread -lm
|
||||
sha256sum ./dist/png_$(PLATFORM)_$(ARCH).bin | awk '{ printf $$1 }' > dist/png_$(PLATFORM)_$(ARCH).bin.sha256
|
||||
|
||||
raw: image_raw.o image_jpeg.o
|
||||
gcc -Wall -c src/main_raw_to_jpeg.c -o src/main_raw_to_jpeg.o
|
||||
# libraw was configured like this: ./configure --disable-openmp --disable-lcms
|
||||
g++ -static src/main_raw_to_jpeg.o src/image_raw.o src/image_jpeg.o -o dist/raw_$(PLATFORM)_$(ARCH).bin -l:libraw.a -l:libjpeg.a -l:libz.a -l:libstdc++.a -lm
|
||||
sha256sum ./dist/raw_$(PLATFORM)_$(ARCH).bin | awk '{ printf $$1 }' > dist/raw_$(PLATFORM)_$(ARCH).bin.sha256
|
||||
|
||||
clean:
|
||||
rm src/*.o dist/*_$(PLATFORM)_$(ARCH).bin* || true
|
||||
|
||||
test:
|
||||
@gcc -Wall src/test.c -o test.bin -ljpeg -lpng -lz -lwebp -lpthread -lm -lraw
|
||||
@./test.bin /home/mickael/Downloads/
|
||||
@rm test.bin
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
db54aaaa47c9b08763d804e6a6e5f4bc0513512283e940bbbc9c0eb4948b3330
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
3356b3016e1b45654889399e78fee04eaeb29a03d0d7f8ab2465609cbf1ec20d
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
e4ec493a64ed971bad119bce2bb8f4790876a3bd41a30419dfca7fd66cc20830
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
d1d02d84c18e18ce639afaf35335a476eea5deebc5aa31aeb45f052abcd1f31d
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
2a377fad44b4dd63581c7e5ec736705c4700ff278fec8c477685ca45953da57b
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
a67be4a057bf7053ea1f5a52b789cc92f2a176387d25ccfe4c2620484d4b0adf
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
1e0ea798cadb3ed4af0e562e4044acae98f4c6db822b354d3623039e5b42ece9
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
198cc17684799587cee23fee02df161822cc26a34dfed3ac70a3e29632813ab8
|
||||
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
63e800f314d0392475dec307feaa26440eca116d27233c0a1171a0cc98e28fb4
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
. "github.com/mickael-kerjean/filestash/server/common"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:embed dist/placeholder.png
|
||||
var placeholder []byte
|
||||
|
||||
func init() {
|
||||
Hooks.Register.Thumbnailer("image/png", thumbnailBuilder{thumbnailPng})
|
||||
Hooks.Register.Thumbnailer("image/jpeg", thumbnailBuilder{thumbnailJpeg})
|
||||
for _, mType := range []string{
|
||||
"image/x-canon-cr2", "image/x-fuji-raf", "image/x-nikon-nef",
|
||||
"image/x-nikon-nrw", "image/x-epson-erf",
|
||||
} {
|
||||
Hooks.Register.Thumbnailer(mType, thumbnailBuilder{thumbnailRaw})
|
||||
}
|
||||
Hooks.Register.ProcessFileContentBeforeSend(renderRaw)
|
||||
}
|
||||
|
||||
func thumbnailPng(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||
h := (*res).Header()
|
||||
r, err := createThumbnailForPng(reader)
|
||||
if err != nil {
|
||||
h.Set("Content-Type", "image/png")
|
||||
h.Set("Cache-Control", "max-age=1")
|
||||
return NewReadCloserFromBytes(placeholder), nil
|
||||
}
|
||||
h.Set("Content-Type", "image/webp")
|
||||
h.Set("Cache-Control", fmt.Sprintf("max-age=%d", 3600*12))
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func thumbnailJpeg(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||
h := (*res).Header()
|
||||
r, err := createThumbnailForJpeg(reader)
|
||||
if err != nil {
|
||||
h.Set("Content-Type", "image/png")
|
||||
h.Set("Cache-Control", "max-age=1")
|
||||
return NewReadCloserFromBytes(placeholder), nil
|
||||
}
|
||||
h.Set("Content-Type", "image/jpeg")
|
||||
h.Set("Cache-Control", fmt.Sprintf("max-age=%d", 3600*12))
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func thumbnailRaw(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||
h := (*res).Header()
|
||||
r, err := createThumbnailForRaw(reader)
|
||||
if err != nil {
|
||||
h.Set("Content-Type", "image/png")
|
||||
h.Set("Cache-Control", "max-age=1")
|
||||
return NewReadCloserFromBytes(placeholder), nil
|
||||
}
|
||||
h.Set("Content-Type", "image/jpeg")
|
||||
h.Set("Cache-Control", fmt.Sprintf("max-age=%d", 3600*12))
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func renderRaw(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||
query := req.URL.Query()
|
||||
if query.Get("thumbnail") == "true" {
|
||||
return reader, nil
|
||||
} else if isRaw(GetMimeType(query.Get("path"))) == false {
|
||||
return reader, nil
|
||||
} else if query.Get("size") == "" {
|
||||
return reader, nil
|
||||
}
|
||||
|
||||
h := (*res).Header()
|
||||
r, err := createRenderingForRaw(reader, query.Get("size"))
|
||||
if err != nil {
|
||||
h.Set("Content-Type", "image/png")
|
||||
return NewReadCloserFromBytes(placeholder), nil
|
||||
}
|
||||
h.Set("Content-Type", "image/jpeg")
|
||||
h.Set("Cache-Control", fmt.Sprintf("max-age=%d", 3600*12))
|
||||
return r, nil
|
||||
}
|
||||
|
||||
type thumbnailBuilder struct {
|
||||
fn func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error)
|
||||
}
|
||||
|
||||
func (this thumbnailBuilder) Generate(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
|
||||
return this.fn(reader, ctx, res, req)
|
||||
}
|
||||
|
||||
type ThumbnailExecutable struct {
|
||||
Name string
|
||||
Binary *[]byte
|
||||
Checksum []byte
|
||||
isValid bool
|
||||
lastVerify time.Time
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (this ThumbnailExecutable) Init() {
|
||||
p := "/tmp/" + this.Name
|
||||
f, err := os.OpenFile(p, os.O_RDONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
outFile, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
Log.Warning("plg_image_thumbnail::init::run::openFile '%s'", this.Name)
|
||||
return
|
||||
}
|
||||
outFile.Write(*this.Binary)
|
||||
if err = outFile.Close(); err != nil {
|
||||
Log.Warning("plg_image_thumbnail::init::run::close '%s'", this.Name)
|
||||
return
|
||||
}
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
||||
func (this *ThumbnailExecutable) verify() bool {
|
||||
this.Lock()
|
||||
defer this.Unlock()
|
||||
if time.Since(this.lastVerify) > 30*time.Second {
|
||||
this.lastVerify = time.Now()
|
||||
f, err := os.OpenFile("/tmp/"+this.Name, os.O_RDONLY, os.ModePerm)
|
||||
if err == nil && bytes.Equal([]byte(HashStream(f, 0)), this.Checksum) {
|
||||
this.isValid = true
|
||||
}
|
||||
}
|
||||
return this.isValid
|
||||
}
|
||||
|
||||
func (this *ThumbnailExecutable) Execute(reader io.ReadCloser, params ...string) (io.ReadCloser, error) {
|
||||
if this.verify() == false {
|
||||
Log.Error("plg_image_thumbnail::execution abort after verification on '%s'", this.Name)
|
||||
reader.Close()
|
||||
return nil, ErrFilesystemError
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
var errBuff bytes.Buffer
|
||||
cmd := exec.Command("/tmp/"+this.Name, params...)
|
||||
cmd.Stdin = reader
|
||||
cmd.Stdout = &buf
|
||||
cmd.Stderr = &errBuff
|
||||
if err := cmd.Run(); err != nil {
|
||||
reader.Close()
|
||||
Log.Debug("plg_image_thumbmail::resize %s ERR %s", this.Name, string(errBuff.Bytes()))
|
||||
return nil, errors.New(string(errBuff.Bytes()))
|
||||
}
|
||||
cmd.Wait()
|
||||
reader.Close()
|
||||
return NewReadCloserFromBytes(buf.Bytes()), nil
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var exeForJpeg ThumbnailExecutable = ThumbnailExecutable{
|
||||
Name: "thumbnail_jpeg.bin",
|
||||
Binary: &binaryThumbnailJpeg,
|
||||
Checksum: checksumJpeg,
|
||||
}
|
||||
|
||||
func init() {
|
||||
exeForJpeg.Init()
|
||||
}
|
||||
|
||||
func createThumbnailForJpeg(reader io.ReadCloser) (io.ReadCloser, error) {
|
||||
return exeForJpeg.Execute(reader)
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/jpeg_linux_amd64.bin
|
||||
var binaryThumbnailJpeg []byte
|
||||
|
||||
//go:embed dist/jpeg_linux_amd64.bin.sha256
|
||||
var checksumJpeg []byte
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/jpeg_linux_arm.bin
|
||||
var binaryThumbnailJpeg []byte
|
||||
|
||||
//go:embed dist/jpeg_linux_arm.bin.sha256
|
||||
var checksumJpeg []byte
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/jpeg_linux_arm64.bin
|
||||
var binaryThumbnailJpeg []byte
|
||||
|
||||
//go:embed dist/jpeg_linux_arm64.bin.sha256
|
||||
var checksumJpeg []byte
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var exeForPng ThumbnailExecutable = ThumbnailExecutable{
|
||||
Name: "thumbnail_png.bin",
|
||||
Binary: &binaryThumbnailPng,
|
||||
Checksum: checksumPng,
|
||||
}
|
||||
|
||||
func init() {
|
||||
exeForPng.Init()
|
||||
}
|
||||
|
||||
func createThumbnailForPng(reader io.ReadCloser) (io.ReadCloser, error) {
|
||||
return exeForPng.Execute(reader)
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/png_linux_amd64.bin
|
||||
var binaryThumbnailPng []byte
|
||||
|
||||
//go:embed dist/png_linux_amd64.bin.sha256
|
||||
var checksumPng []byte
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/png_linux_arm.bin
|
||||
var binaryThumbnailPng []byte
|
||||
|
||||
//go:embed dist/png_linux_arm.bin.sha256
|
||||
var checksumPng []byte
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/png_linux_arm64.bin
|
||||
var binaryThumbnailPng []byte
|
||||
|
||||
//go:embed dist/png_linux_arm64.bin.sha256
|
||||
var checksumPng []byte
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var exeForRaw ThumbnailExecutable = ThumbnailExecutable{
|
||||
Name: "thumbnail_raw.bin",
|
||||
Binary: &binaryThumbnailRaw,
|
||||
Checksum: checksumRaw,
|
||||
}
|
||||
|
||||
func init() {
|
||||
exeForRaw.Init()
|
||||
}
|
||||
|
||||
func createThumbnailForRaw(reader io.ReadCloser) (io.ReadCloser, error) {
|
||||
return exeForRaw.Execute(reader, "200")
|
||||
}
|
||||
|
||||
func createRenderingForRaw(reader io.ReadCloser, size string) (io.ReadCloser, error) {
|
||||
return exeForRaw.Execute(reader, size)
|
||||
}
|
||||
|
||||
func isRaw(mType string) bool {
|
||||
switch mType {
|
||||
case "image/x-tif":
|
||||
case "image/x-canon-cr2":
|
||||
case "image/x-canon-crw":
|
||||
case "image/x-nikon-nef":
|
||||
case "image/x-nikon-nrw":
|
||||
case "image/x-sony-arw":
|
||||
case "image/x-sony-sr2":
|
||||
case "image/x-minolta-mrw":
|
||||
case "image/x-minolta-mdc":
|
||||
case "image/x-olympus-orf":
|
||||
case "image/x-panasonic-rw2":
|
||||
case "image/x-pentax-pef":
|
||||
case "image/x-epson-erf":
|
||||
case "image/x-raw":
|
||||
case "image/x-x3f":
|
||||
case "image/x-fuji-raf":
|
||||
case "image/x-aptus-mos":
|
||||
case "image/x-mamiya-mef":
|
||||
case "image/x-hasselblad-3fr":
|
||||
case "image/x-adobe-dng":
|
||||
case "image/x-samsung-srw":
|
||||
case "image/x-kodak-kdc":
|
||||
case "image/x-kodak-dcr":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/raw_linux_amd64.bin
|
||||
var binaryThumbnailRaw []byte
|
||||
|
||||
//go:embed dist/raw_linux_amd64.bin.sha256
|
||||
var checksumRaw []byte
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/raw_linux_arm.bin
|
||||
var binaryThumbnailRaw []byte
|
||||
|
||||
//go:embed dist/raw_linux_arm.bin.sha256
|
||||
var checksumRaw []byte
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package plg_image_thumbnail
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed dist/raw_linux_arm64.bin
|
||||
var binaryThumbnailRaw []byte
|
||||
|
||||
//go:embed dist/raw_linux_arm64.bin.sha256
|
||||
var checksumRaw []byte
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "utils.h"
|
||||
#include "jpeglib.h"
|
||||
// #include "webp/encode.h"
|
||||
|
||||
#define JPEG_QUALITY 50
|
||||
|
||||
int jpeg_to_jpeg(FILE* input, FILE* output, int targetSize) {
|
||||
#ifdef HAS_DEBUG
|
||||
clock_t t;
|
||||
t = clock();
|
||||
#endif
|
||||
|
||||
struct jpeg_decompress_struct jpeg_config_input;
|
||||
struct jpeg_compress_struct jpeg_config_output;
|
||||
struct jpeg_error_mgr jerr;
|
||||
int jpeg_row_stride;
|
||||
int image_min_size;
|
||||
JSAMPARRAY buffer;
|
||||
|
||||
jpeg_config_input.err = jpeg_std_error(&jerr);
|
||||
jpeg_config_output.err = jpeg_std_error(&jerr);
|
||||
jpeg_config_input.dct_method = JDCT_IFAST;
|
||||
jpeg_config_input.do_fancy_upsampling = FALSE;
|
||||
jpeg_config_input.two_pass_quantize = FALSE;
|
||||
jpeg_config_input.dither_mode = JDITHER_ORDERED;
|
||||
|
||||
jpeg_create_decompress(&jpeg_config_input);
|
||||
jpeg_create_compress(&jpeg_config_output);
|
||||
jpeg_stdio_src(&jpeg_config_input, input);
|
||||
jpeg_stdio_dest(&jpeg_config_output, output);
|
||||
DEBUG("after constructor decompress");
|
||||
if(jpeg_read_header(&jpeg_config_input, TRUE) != JPEG_HEADER_OK) {
|
||||
jpeg_destroy_decompress(&jpeg_config_input);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("after header read");
|
||||
jpeg_config_input.dct_method = JDCT_IFAST;
|
||||
jpeg_config_input.do_fancy_upsampling = FALSE;
|
||||
jpeg_config_input.two_pass_quantize = FALSE;
|
||||
jpeg_config_input.dither_mode = JDITHER_ORDERED;
|
||||
jpeg_calc_output_dimensions(&jpeg_config_input);
|
||||
|
||||
image_min_size = min(jpeg_config_input.output_width, jpeg_config_input.output_height);
|
||||
jpeg_config_input.scale_num = 1;
|
||||
jpeg_config_input.scale_denom = 1;
|
||||
if (image_min_size / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 1;
|
||||
jpeg_config_input.scale_denom = 8;
|
||||
} else if (image_min_size * 2 / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 1;
|
||||
jpeg_config_input.scale_denom = 4;
|
||||
} else if (image_min_size * 3 / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 3;
|
||||
jpeg_config_input.scale_denom = 8;
|
||||
} else if (image_min_size * 4 / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 4;
|
||||
jpeg_config_input.scale_denom = 8;
|
||||
} else if (image_min_size * 5 / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 5;
|
||||
jpeg_config_input.scale_denom = 8;
|
||||
} else if (image_min_size * 6 / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 6;
|
||||
jpeg_config_input.scale_denom = 8;
|
||||
} else if (image_min_size * 7 / 8 >= targetSize) {
|
||||
jpeg_config_input.scale_num = 7;
|
||||
jpeg_config_input.scale_denom = 8;
|
||||
}
|
||||
|
||||
DEBUG("start decompress");
|
||||
if(jpeg_start_decompress(&jpeg_config_input) == FALSE) {
|
||||
jpeg_destroy_decompress(&jpeg_config_input);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("processing image");
|
||||
jpeg_row_stride = jpeg_config_input.output_width * jpeg_config_input.output_components;
|
||||
jpeg_config_output.image_width = jpeg_config_input.output_width;
|
||||
jpeg_config_output.image_height = jpeg_config_input.output_height;
|
||||
jpeg_config_output.input_components = jpeg_config_input.num_components;
|
||||
jpeg_config_output.in_color_space = JCS_RGB;
|
||||
jpeg_set_defaults(&jpeg_config_output);
|
||||
jpeg_set_quality(&jpeg_config_output, JPEG_QUALITY, TRUE);
|
||||
jpeg_start_compress(&jpeg_config_output, TRUE);
|
||||
|
||||
buffer = (*jpeg_config_input.mem->alloc_sarray) ((j_common_ptr) &jpeg_config_input, JPOOL_IMAGE, jpeg_row_stride, 1);
|
||||
while (jpeg_config_input.output_scanline < jpeg_config_input.output_height) {
|
||||
// TODO: scanlines should return 1
|
||||
jpeg_read_scanlines(&jpeg_config_input, buffer, 1);
|
||||
jpeg_write_scanlines(&jpeg_config_output, buffer, 1);
|
||||
}
|
||||
DEBUG("end decompress");
|
||||
jpeg_finish_decompress(&jpeg_config_input);
|
||||
jpeg_destroy_decompress(&jpeg_config_input);
|
||||
DEBUG("finish decompress");
|
||||
jpeg_finish_compress(&jpeg_config_output);
|
||||
DEBUG("final");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static int MyWriter(const uint8_t* data, size_t data_size,
|
||||
const WebPPicture* const pic) {
|
||||
FILE* const out = (FILE*)pic->custom_ptr;
|
||||
return data_size ? (fwrite(data, data_size, 1, out) == 1) : 1;
|
||||
}
|
||||
|
||||
int jpeg_to_webp(FILE* input, FILE* output) {
|
||||
#ifdef HAS_DEBUG
|
||||
clock_t t;
|
||||
t = clock();
|
||||
#endif
|
||||
|
||||
struct jpeg_decompress_struct jpeg_config_input;
|
||||
struct jpeg_error_mgr jerr;
|
||||
u_int8_t* volatile rgb = NULL;
|
||||
JSAMPROW buffer[1];
|
||||
int jpeg_row_stride;
|
||||
|
||||
jpeg_config_input.err = jpeg_std_error(&jerr);
|
||||
jpeg_config_input.dct_method = JDCT_IFAST;
|
||||
jpeg_config_input.do_fancy_upsampling = FALSE;
|
||||
jpeg_config_input.two_pass_quantize = FALSE;
|
||||
jpeg_config_input.dither_mode = JDITHER_ORDERED;
|
||||
|
||||
jpeg_create_decompress(&jpeg_config_input);
|
||||
jpeg_stdio_src(&jpeg_config_input, input);
|
||||
|
||||
DEBUG("after constructor decompress");
|
||||
if(jpeg_read_header(&jpeg_config_input, TRUE) != JPEG_HEADER_OK) {
|
||||
jpeg_destroy_decompress(&jpeg_config_input);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("after header read");
|
||||
jpeg_config_input.dct_method = JDCT_IFAST;
|
||||
jpeg_config_input.do_fancy_upsampling = FALSE;
|
||||
jpeg_config_input.two_pass_quantize = FALSE;
|
||||
jpeg_config_input.dither_mode = JDITHER_ORDERED;
|
||||
jpeg_calc_output_dimensions(&jpeg_config_input);
|
||||
DEBUG("start decompress");
|
||||
if(jpeg_start_decompress(&jpeg_config_input) == FALSE) {
|
||||
jpeg_destroy_decompress(&jpeg_config_input);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("hot");
|
||||
jpeg_row_stride = jpeg_config_input.output_width * jpeg_config_input.output_components;
|
||||
|
||||
rgb = (u_int8_t*)malloc(jpeg_config_input.output_height * jpeg_row_stride);
|
||||
buffer[0] = (JSAMPLE*)rgb;
|
||||
while (jpeg_config_input.output_scanline < jpeg_config_input.output_height) {
|
||||
jpeg_read_scanlines(&jpeg_config_input, buffer, 1);
|
||||
buffer[0] += jpeg_row_stride;
|
||||
}
|
||||
DEBUG("end decompress");
|
||||
jpeg_finish_decompress(&jpeg_config_input);
|
||||
jpeg_destroy_decompress(&jpeg_config_input);
|
||||
|
||||
DEBUG("finish decompress");
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// ENCODE
|
||||
// resize: https://chromium.googlesource.com/webm/libwebp/+/0.2.0/examples/cwebp.c#1174
|
||||
WebPPicture picture;
|
||||
|
||||
if (!WebPPictureInit(&picture)) {
|
||||
DEBUG("ERR picture init");
|
||||
return 1;
|
||||
}
|
||||
|
||||
picture.width = jpeg_config_input.output_width;
|
||||
picture.height = jpeg_config_input.output_height;
|
||||
if(!WebPPictureAlloc(&picture)) {
|
||||
DEBUG("ALLOC ERR");
|
||||
return 1;
|
||||
}
|
||||
WebPPictureImportRGB(&picture, rgb, jpeg_row_stride);
|
||||
|
||||
WebPConfig webp_config_output;
|
||||
picture.writer = MyWriter;
|
||||
picture.custom_ptr = output;
|
||||
if (!WebPConfigInit(&webp_config_output)) {
|
||||
DEBUG("ERR config init");
|
||||
return 1;
|
||||
}
|
||||
webp_config_output.image_hint = WEBP_HINT_PHOTO;
|
||||
webp_config_output.method = 0;
|
||||
|
||||
if (!WebPValidateConfig(&webp_config_output)) {
|
||||
DEBUG("ERR WEB VALIDATION");
|
||||
}
|
||||
fprintf(stderr, "rescale start %F\n", ((double)clock() - t)/CLOCKS_PER_SEC * 1000);
|
||||
if (!WebPPictureRescale(&picture, jpeg_config_input.output_width / 4, jpeg_config_input.output_height / 4)) {
|
||||
DEBUG("ERR Rescale");
|
||||
}
|
||||
DEBUG("encoder start");
|
||||
WebPEncode(&webp_config_output, &picture);
|
||||
DEBUG("encoder done");
|
||||
WebPPictureFree(&picture);
|
||||
DEBUG("everything is free");
|
||||
}
|
||||
*/
|
||||
void jpeg_size(FILE* infile, int* height, int* width) {
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_stdio_src(&cinfo, infile);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
*width = cinfo.image_width;
|
||||
*height = cinfo.image_height;
|
||||
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "jpeglib.h"
|
||||
#include "utils.h"
|
||||
|
||||
void jpeg_size(FILE* infile, int* height, int* width);
|
||||
|
||||
int jpeg_to_jpeg(FILE* input, FILE* output, int targetSize);
|
||||
|
||||
int jpeg_to_webp(FILE* input, FILE* output, int targetSize);
|
||||
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <png.h>
|
||||
#include "webp/encode.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int MyWriter(const uint8_t* data, size_t data_size, const WebPPicture* const pic) {
|
||||
FILE* const out = (FILE*)pic->custom_ptr;
|
||||
return data_size ? (fwrite(data, data_size, 1, out) == 1) : 1;
|
||||
}
|
||||
|
||||
int png_to_webp(FILE* input, FILE* output, int targetSize) {
|
||||
WebPPicture picture;
|
||||
|
||||
#ifdef HAS_DEBUG
|
||||
clock_t t;
|
||||
t = clock();
|
||||
#endif
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof image);
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
DEBUG("reading png");
|
||||
if (!png_image_begin_read_from_stdio(&image, input)) {
|
||||
ERROR("png_image_begin_read_from_stdio");
|
||||
return 1;
|
||||
}
|
||||
DEBUG("allocate");
|
||||
png_bytep buffer;
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
buffer = malloc(PNG_IMAGE_SIZE(image));
|
||||
if (buffer == NULL) {
|
||||
ERROR("png_malloc");
|
||||
png_image_free(&image);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("start reading");
|
||||
if (!png_image_finish_read(&image, NULL, buffer, 0, NULL)) {
|
||||
ERROR("png_image_finish_read");
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// encode to webp
|
||||
DEBUG("start encoding");
|
||||
if (!WebPPictureInit(&picture)) {
|
||||
ERROR("WebPPictureInit");
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
picture.width = image.width;
|
||||
picture.height = image.height;
|
||||
if(!WebPPictureAlloc(&picture)) {
|
||||
ERROR("WebPPictureAlloc");
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("start encoding import");
|
||||
WebPPictureImportRGBA(&picture, buffer, PNG_IMAGE_ROW_STRIDE(image));
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
|
||||
WebPConfig webp_config_output;
|
||||
picture.writer = MyWriter;
|
||||
picture.custom_ptr = output;
|
||||
DEBUG("start encoding config init");
|
||||
if (!WebPConfigInit(&webp_config_output)) {
|
||||
ERROR("ERR config init");
|
||||
WebPPictureFree(&picture);
|
||||
return 1;
|
||||
}
|
||||
webp_config_output.method = 0;
|
||||
webp_config_output.quality = 30;
|
||||
if (!WebPValidateConfig(&webp_config_output)) {
|
||||
ERROR("ERR WEB VALIDATION");
|
||||
WebPPictureFree(&picture);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("rescale start");
|
||||
if (image.width > targetSize && image.height > targetSize) {
|
||||
float ratioHeight = (float) image.height / targetSize;
|
||||
float ratioWidth = (float) image.width / targetSize;
|
||||
float ratio = ratioWidth > ratioHeight ? ratioHeight : ratioWidth;
|
||||
if (!WebPPictureRescale(&picture, image.width / ratio, image.height / ratio)) {
|
||||
DEBUG("ERR Rescale");
|
||||
WebPPictureFree(&picture);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
DEBUG("encoder start");
|
||||
WebPEncode(&webp_config_output, &picture);
|
||||
DEBUG("encoder done");
|
||||
WebPPictureFree(&picture);
|
||||
DEBUG("cleaning up");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int png_to_png(FILE* input, FILE* output, int targetSize) {
|
||||
#ifdef HAS_DEBUG
|
||||
clock_t t;
|
||||
t = clock();
|
||||
#endif
|
||||
png_image image;
|
||||
memset(&image, 0, sizeof image);
|
||||
image.version = PNG_IMAGE_VERSION;
|
||||
DEBUG("> reading png");
|
||||
if (!png_image_begin_read_from_stdio(&image, input)) {
|
||||
DEBUG("png_image_begin_read_from_stdio");
|
||||
return 1;
|
||||
}
|
||||
DEBUG("> allocate");
|
||||
png_bytep buffer;
|
||||
image.format = PNG_FORMAT_RGBA;
|
||||
buffer = malloc(PNG_IMAGE_SIZE(image));
|
||||
if (buffer == NULL) {
|
||||
DEBUG("png_malloc");
|
||||
png_image_free(&image);
|
||||
return 1;
|
||||
}
|
||||
DEBUG("> start reading");
|
||||
if (!png_image_finish_read(&image, NULL, buffer, 0, NULL)) {
|
||||
DEBUG("png_image_finish_read");
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG("> write");
|
||||
if (!png_image_write_to_stdio(&image, output, 0, buffer, 0, NULL)) {
|
||||
DEBUG("png_image_write_to_stdio");
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG("> end");
|
||||
png_image_free(&image);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int png_to_webp(FILE* input, FILE* output, int targetSize);
|
||||
|
||||
int png_to_png(FILE* input, FILE* output, int targetSize);
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <libraw/libraw.h>
|
||||
#include "utils.h"
|
||||
#include "image_jpeg.h"
|
||||
|
||||
#define BUF_SIZE 1024 * 1024
|
||||
|
||||
int raw_to_jpeg(FILE* input, FILE* output, int targetSize) {
|
||||
#ifdef HAS_DEBUG
|
||||
clock_t t;
|
||||
t = clock();
|
||||
#endif
|
||||
|
||||
char fname_in[32] = "/tmp/filestash.XXXXXX";
|
||||
int _mkstemp_in = mkstemp(fname_in);
|
||||
if (_mkstemp_in == -1) {
|
||||
ERROR("mkstemp_in");
|
||||
return 1;
|
||||
}
|
||||
FILE* f_in = fdopen(_mkstemp_in, "w");
|
||||
if (f_in == NULL) {
|
||||
remove(fname_in);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char content[BUF_SIZE];
|
||||
int read;
|
||||
while ((read = fread(content, sizeof(char), BUF_SIZE, input))) {
|
||||
fwrite(content, read, sizeof(char), f_in);
|
||||
}
|
||||
|
||||
DEBUG("libraw init");
|
||||
libraw_data_t *raw = libraw_init(0);
|
||||
DEBUG("libraw open file");
|
||||
if (libraw_open_file(raw, fname_in) != 0) {
|
||||
ERROR("libraw_open_file");
|
||||
libraw_close(raw);
|
||||
fclose(f_in);
|
||||
remove(fname_in);
|
||||
return 1;
|
||||
}
|
||||
|
||||
raw->params.output_tiff = 1;
|
||||
DEBUG("libraw unpack thumb");
|
||||
char fname_out[32] = "/tmp/filestash.XXXXXX";
|
||||
int _mkstemp_out = mkstemp(fname_out);
|
||||
if (_mkstemp_out == -1) {
|
||||
ERROR("mkstemp_out");
|
||||
remove(fname_in);
|
||||
fclose(f_in);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (libraw_unpack_thumb(raw) == 0 && raw->thumbnail.tformat == LIBRAW_THUMBNAIL_JPEG) {
|
||||
DEBUG("has an embed thumbnail");
|
||||
if (libraw_dcraw_thumb_writer(raw, fname_out) == 0) {
|
||||
DEBUG("process thumbnail");
|
||||
libraw_close(raw);
|
||||
FILE* f_out = fdopen(_mkstemp_out, "r");
|
||||
int err = jpeg_to_jpeg(f_out, output, targetSize);
|
||||
fclose(f_out);
|
||||
fclose(f_in);
|
||||
remove(fname_in);
|
||||
remove(fname_out);
|
||||
DEBUG("process complete");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR("not implemented - abort");
|
||||
// if (libraw_unpack(raw) != 0) DEBUG("HERE0");
|
||||
// if (libraw_dcraw_process(raw) != 0) DEBUG("HERE1");
|
||||
// if (libraw_dcraw_ppm_tiff_writer(raw, fname_out) != 0) DEBUG("HERE2");
|
||||
// if (libraw_dcraw_thumb_writer(raw, fname_out) != 0) DEBUG("HERE3");
|
||||
// DEBUG("HERE__");
|
||||
fclose(f_in);
|
||||
remove(fname_in);
|
||||
remove(fname_out);
|
||||
libraw_close(raw);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <libraw/libraw.h>
|
||||
#include "utils.h"
|
||||
#include "image_jpeg.h"
|
||||
|
||||
int raw_to_jpeg(FILE* input, FILE* output, int targetSize);
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "webp/decode.h"
|
||||
|
||||
#define DEFAULT_SIZE 100
|
||||
#define STEP_SIZE 100
|
||||
|
||||
void webp_size(FILE* infile, int* height, int* width) {
|
||||
uint8_t *buffer[DEFAULT_SIZE];
|
||||
size_t buffer_sz=DEFAULT_SIZE;
|
||||
size_t i=0;
|
||||
while (!feof(infile)) {
|
||||
// buffer[i] = fgetc(infile);
|
||||
fread(buffer, buffer_sz+1, sizeof(char), infile);
|
||||
i++;
|
||||
if (i >= buffer_sz) {
|
||||
buffer_sz += STEP_SIZE;
|
||||
void *tmp = buffer;
|
||||
buffer = realloc(buffer, buffer_sz);
|
||||
if (buffer == NULL) {
|
||||
free(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WebPGetInfo(buffer, buffer_sz, height, width);
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void webp_size(FILE* infile, int* height, int* width);
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "jpeglib.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define JPEG_QUALITY 50
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "image_jpeg.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return jpeg_to_jpeg(stdin, stdout, 200);
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "image_png.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return png_to_webp(stdin, stdout, 200);
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#include "image_raw.h"
|
||||
|
||||
int main(int args, const char **argv) {
|
||||
int targetSize = 200;
|
||||
if(args >= 2) {
|
||||
targetSize = atoi(argv[1]);
|
||||
}
|
||||
return raw_to_jpeg(stdin, stdout, targetSize);
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <png.h>
|
||||
#include "webp/encode.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int MyWriter(const uint8_t* data, size_t data_size, const WebPPicture* const pic) {
|
||||
FILE* const out = (FILE*)pic->custom_ptr;
|
||||
return data_size ? (fwrite(data, data_size, 1, out) == 1) : 1;
|
||||
}
|
||||
|
||||
int png_to_webp(FILE* input, FILE* output) {
|
||||
|
||||
}
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include "utils.h"
|
||||
#include "jpeg_to_jpeg.h"
|
||||
#include "png_to_webp.h"
|
||||
#include "jpeg.h"
|
||||
// #include "webp.h"
|
||||
|
||||
int strEndsWith(const char *s, const char *suff) {
|
||||
size_t slen = strlen(s);
|
||||
size_t sufflen = strlen(suff);
|
||||
return slen >= sufflen && !memcmp(s + slen - sufflen, suff, sufflen);
|
||||
}
|
||||
|
||||
void test_jpeg_to_jpeg(const char* basefolder) {
|
||||
struct dirent *de;
|
||||
DIR *dp;
|
||||
int n = 0;
|
||||
clock_t t = clock();
|
||||
|
||||
DEBUG("==================");
|
||||
DEBUG("TEST: jpeg_to_jpeg");
|
||||
dp = opendir(basefolder);
|
||||
assert(dp != NULL);
|
||||
remove("/tmp/out.dat");
|
||||
while ((de = readdir (dp)) != NULL) {
|
||||
if (strEndsWith(de->d_name, ".jpeg") == 0 && strEndsWith(de->d_name, ".jpg") == 0) {
|
||||
continue;
|
||||
}
|
||||
// STEP1: setup the test
|
||||
n += 1;
|
||||
char input_fname[2048] = "";
|
||||
strcpy(input_fname, basefolder);
|
||||
strcat(input_fname, de->d_name);
|
||||
fprintf(stderr, "= Processing[%s]:\n", input_fname);
|
||||
FILE* input = fopen(input_fname, "r");
|
||||
FILE* output = fopen("/tmp/out.dat", "w");
|
||||
|
||||
// STEP2: run the test
|
||||
int ret = jpeg_to_jpeg(input, output);
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
|
||||
// STEP3: assertions
|
||||
int width = -1;
|
||||
int height = -1;
|
||||
output = fopen("/tmp/out.dat", "r");
|
||||
jpeg_size(output, &width, &height);
|
||||
fclose(output);
|
||||
if (width < 0 || width > 800) {
|
||||
fprintf(stderr, "%dx%d", width, height);
|
||||
assert("width outside range" == NULL);
|
||||
}
|
||||
if (height < 0 || height > 800) {
|
||||
fprintf(stderr, "height[%d]", height);
|
||||
assert("height outside range" == NULL);
|
||||
}
|
||||
assert(ret == 0);
|
||||
remove("/tmp/out.dat");
|
||||
}
|
||||
assert(n > 0);
|
||||
closedir(dp);
|
||||
}
|
||||
|
||||
void test_png_to_webp(const char* basefolder) {
|
||||
struct dirent *de;
|
||||
DIR *dp;
|
||||
int n = 0;
|
||||
clock_t t = clock();
|
||||
|
||||
DEBUG("==================");
|
||||
DEBUG("TEST: png_to_webp");
|
||||
dp = opendir(basefolder);
|
||||
assert(dp != NULL);
|
||||
remove("/tmp/out.dat");
|
||||
while ((de = readdir (dp)) != NULL) {
|
||||
if (strEndsWith(de->d_name, ".png") == 0) {
|
||||
continue;
|
||||
}
|
||||
// STEP1: setup the test
|
||||
n += 1;
|
||||
char input_fname[2048] = "";
|
||||
strcpy(input_fname, basefolder);
|
||||
strcat(input_fname, de->d_name);
|
||||
fprintf(stderr, "= Processing[%s]:\n", input_fname);
|
||||
FILE* input = fopen(input_fname, "r");
|
||||
FILE* output = fopen("/tmp/out.dat", "w");
|
||||
|
||||
// STEP2: run the test
|
||||
int ret = png_to_webp(input, output);
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
|
||||
// STEP3: assertions
|
||||
int width = -1;
|
||||
int height = -1;
|
||||
output = fopen("/tmp/out.dat", "r");
|
||||
// webp_size(output, &width, &height);
|
||||
fclose(output);
|
||||
if (width < 0 || width > 800) {
|
||||
fprintf(stderr, "%dx%d", width, height);
|
||||
assert("width outside range" == NULL);
|
||||
}
|
||||
if (height < 0 || height > 800) {
|
||||
fprintf(stderr, "height[%d]", height);
|
||||
assert("height outside range" == NULL);
|
||||
}
|
||||
assert(ret == 0);
|
||||
remove("/tmp/out.dat");
|
||||
}
|
||||
assert(n > 0);
|
||||
closedir(dp);
|
||||
}
|
||||
|
||||
void test_raw_to_jpeg(const char* basename) {
|
||||
clock_t t = clock();
|
||||
DEBUG("==================");
|
||||
DEBUG("(TODO)TEST: raw_to_jpeg");
|
||||
}
|
||||
|
||||
int main(int args, const char **argv) {
|
||||
if (args != 2) {
|
||||
ERROR("need path with pictures in argument");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// test_jpeg_to_jpeg(argv[1]);
|
||||
// test_png_to_webp(argv[1]);
|
||||
// test_raw_to_jpeg(argv[1]);
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#define HAS_DEBUG 1
|
||||
#if HAS_DEBUG == 1
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#define DEBUG(r) (fprintf(stderr, "[DEBUG::('" r "')(%.2Fms)]", ((double)clock() - t)/CLOCKS_PER_SEC * 1000))
|
||||
#else
|
||||
#define DEBUG(r) ((void)0)
|
||||
#endif
|
||||
|
||||
#define ERROR(r) (fprintf(stderr, "[ERROR:('" r "')]"))
|
||||
|
||||
#define min(a, b) (a > b ? b : a)
|
||||
Loading…
Reference in a new issue