6 files changed, 8 insertions(+), 233 deletions(-)
R avif.go =>
M go.mod
M go.sum
R lazif.c =>
R lazif.h =>
M main.go
R avif.go => +0 -80
@@ 1,80 0,0 @@
-package main
-
-/*
-#include <stdlib.h>
-#include <string.h>
-
-#include "lazif.h"
-*/
-import "C"
-import (
- "bytes"
- "image"
- "image/jpeg"
- "runtime"
- "sync"
- "unsafe"
-)
-
-var avifOnce sync.Once
-var avifLoaded bool
-
-func avifInit() {
- rv := C.lazifInit()
- if rv == 0 {
- avifLoaded = true
- }
-}
-
-func avifEncode(data []byte) []byte {
- avifOnce.Do(avifInit)
- if !avifLoaded {
- return nil
- }
-
- img, err := jpeg.Decode(bytes.NewReader(data))
- if err != nil {
- ilog.Printf("failed to decode")
- return nil
- }
- jpg, ok := img.(*image.YCbCr)
- if !ok {
- ilog.Printf("not jpeg")
- return nil
- }
- switch jpg.SubsampleRatio {
- case image.YCbCrSubsampleRatio420:
- default:
- ilog.Printf("bad sample ratio: %d", jpg.SubsampleRatio)
- return nil
- }
-
- var args C.struct_lazifArgs
-
- args.width = C.uint(jpg.Rect.Max.X)
- args.height = C.uint(jpg.Rect.Max.Y)
-
- var pinner runtime.Pinner
- defer pinner.Unpin()
-
- args.planes[0] = (*C.uchar)(&jpg.Y[0])
- pinner.Pin(args.planes[0])
- args.strides[0] = C.uint(jpg.YStride)
- args.planes[1] = (*C.uchar)(&jpg.Cb[0])
- pinner.Pin(args.planes[1])
- args.strides[1] = C.uint(jpg.CStride)
- args.planes[2] = (*C.uchar)(&jpg.Cr[0])
- pinner.Pin(args.planes[2])
- args.strides[2] = C.uint(jpg.CStride)
-
- rv := C.lazifEncode(&args)
- if rv != 0 {
- ilog.Printf("failed to encode")
- return nil
- }
- res := make([]byte, int(args.outlen))
- C.memcpy(unsafe.Pointer(&res[0]), unsafe.Pointer(args.out), args.outlen)
- C.lazifFree(&args)
-
- return res
-}
M go.mod +1 -1
@@ 11,7 11,7 @@ require (
humungus.tedunangst.com/r/go-sqlite3 v1.2.1
humungus.tedunangst.com/r/gonix v0.1.4
humungus.tedunangst.com/r/termvc v0.1.3
- humungus.tedunangst.com/r/webs v0.7.22
+ humungus.tedunangst.com/r/webs v0.7.23
)
require (
M go.sum +2 -2
@@ 80,5 80,5 @@ humungus.tedunangst.com/r/gonix v0.1.4 h
humungus.tedunangst.com/r/gonix v0.1.4/go.mod h1:VFBc2bPDXr1ayHOmHUutxYu8fSM+pkwK8o36h4rkORg=
humungus.tedunangst.com/r/termvc v0.1.3 h1:BYxcqdA2Ijhqolf2BdNlGw5355qE80EzAqiNgi7d5tk=
humungus.tedunangst.com/r/termvc v0.1.3/go.mod h1:TnlG9PbH77OpEf46iDyb/H9drjegQNwhpXalmGGrbhU=
-humungus.tedunangst.com/r/webs v0.7.22 h1:Whxe2p4WuqZPH1ExugO0HxQwUDI7H7oHQ4YP7vTk8R0=
-humungus.tedunangst.com/r/webs v0.7.22/go.mod h1:ylhqHSPI0Oi7b4nsnx5mSO7AjLXN7wFpEHayLfN/ugk=
+humungus.tedunangst.com/r/webs v0.7.23 h1:LEamoWvtgBOukGuzHj/T1qhRwNQkoz2RMCiwvvxwIug=
+humungus.tedunangst.com/r/webs v0.7.23/go.mod h1:ylhqHSPI0Oi7b4nsnx5mSO7AjLXN7wFpEHayLfN/ugk=
R lazif.c => +0 -137
@@ 1,137 0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <dlfcn.h>
-#include <string.h>
-
-#include "lazif.h"
-
-struct frame {
- uint32_t width;
- uint32_t height;
- uint32_t depth;
-
- int yuvFormat;
- int yuvRange;
- int yuvChromaSamplePosition;
- uint8_t * yuvPlanes[3];
- uint32_t yuvRowBytes[3];
- int imageOwnsYUVPlanes;
-
- uint8_t * alphaPlane;
- uint32_t alphaRowBytes;
- int imageOwnsAlphaPlane;
- int alphaPremultiplied;
-};
-
-struct encoder {
- int codecChoice;
- int maxThreads;
- int speed;
- int keyframeInterval;
- uint64_t timescale;
- int repetitionCount;
- uint32_t extraLayerCount;
- int quality;
- int qualityAlpha;
- int minQuantizer;
- int maxQuantizer;
- int minQuantizerAlpha;
- int maxQuantizerAlpha;
-};
-
-struct rwdata {
- unsigned char *data;
- size_t size;
-};
-
-static struct frame *(*imgCreate)(unsigned int, unsigned int, int, int);
-static struct encoder *(*encCreate)(void);
-static int (*encWrite)(struct encoder *, struct frame *, struct rwdata *);
-static void (*encDestroy)(struct encoder *);
-static void (*imgDestroy)(struct frame *);
-static void (*dataFree)(struct rwdata *);
-
-int
-lazifInit(void)
-{
- void *lib = dlopen("libavif.so", RTLD_LAZY);
- if (!lib) {
- printf("no libavif\n");
- return -1;
- }
- if (!(imgCreate = dlsym(lib, "avifImageCreate"))) {
- printf("no imgCreate\n");
- return -1;
- }
- if (!(encCreate = dlsym(lib, "avifEncoderCreate"))) {
- printf("no encCreate\n");
- return -1;
- }
- if (!(encWrite = dlsym(lib, "avifEncoderWrite"))) {
- printf("no encWrite\n");
- return -1;
- }
- if (!(encDestroy = dlsym(lib, "avifEncoderDestroy"))) {
- printf("no encDestroy\n");
- return -1;
- }
- if (!(imgDestroy = dlsym(lib, "avifImageDestroy"))) {
- printf("no imgDestroy\n");
- return -1;
- }
- if (!(dataFree = dlsym(lib, "avifRWDataFree"))) {
- printf("no dataFree\n");
- return -1;
- }
- return 0;
-}
-
-int
-lazifEncode(struct lazifArgs *args)
-{
- int rv = -1;
- const int yuv420 = 3;
- struct frame *frame = imgCreate(args->width, args->height, 8, yuv420);
- if (!frame)
- goto out;
-
- printf("create frame\n");
- for (int i = 0; i < 3; i++) {
- frame->yuvPlanes[i] = args->planes[i];
- frame->yuvRowBytes[i] = args->strides[i];
- }
-
- struct encoder *enc = encCreate();
- // avifEncoder *enc = avifEncoderCreate();
- if (!enc)
- goto out;
- printf("create enc\n");
- enc->maxThreads = 2;
- enc->speed = 10;
-
- printf("writing image\n");
- struct rwdata out;
- memset(&out, 0, sizeof(out));
- int err = encWrite(enc, frame, &out);
- if (err)
- goto out;
- printf("wrote image\n");
- args->out = out.data;
- args->outlen = out.size;
- rv = 0;
-out:
- if (enc)
- encDestroy(enc);
- if (frame)
- imgDestroy(frame);
- return rv;
-}
-
-void
-lazifFree(struct lazifArgs *args)
-{
- struct rwdata out;
- out.data = args->out;
- out.size = args->outlen;
- dataFree(&out);
-}
R lazif.h => +0 -13
@@ 1,13 0,0 @@
-struct lazifArgs {
- unsigned int width;
- unsigned int height;
- unsigned char *planes[3];
- unsigned int strides[3];
- unsigned char *out;
- size_t outlen;
-};
-
-int lazifInit(void);
-int lazifEncode(struct lazifArgs *args);
-void lazifFree(struct lazifArgs *args);
-
M main.go +5 -0
@@ 30,6 30,7 @@ import (
"strings"
"time"
+ "humungus.tedunangst.com/r/webs/lazif"
"humungus.tedunangst.com/r/webs/log"
)
@@ 60,6 61,10 @@ func ElaborateUnitTests() {
os.WriteFile("output.avif", d2, 0600)
}
+func avifEncode(data []byte) []byte {
+ return lazif.Encode(data)
+}
+
func unplugserver(hostname string) {
db := opendatabase()
xid := fmt.Sprintf("https://%s", hostname)