Refactor: pngmeta rewrite
This commit is contained in:
@@ -1,116 +1,112 @@
|
||||
package pngmeta
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"elefant/models"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
// import (
|
||||
// "bytes"
|
||||
// "encoding/binary"
|
||||
// "errors"
|
||||
// "fmt"
|
||||
// "hash/crc32"
|
||||
// "io"
|
||||
// )
|
||||
|
||||
type Writer struct {
|
||||
w io.Writer
|
||||
}
|
||||
// type Writer struct {
|
||||
// w io.Writer
|
||||
// }
|
||||
|
||||
func NewPNGWriter(w io.Writer) (*Writer, error) {
|
||||
if _, err := io.WriteString(w, writeHeader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Writer{w}, nil
|
||||
}
|
||||
// func NewPNGWriter(w io.Writer) (*Writer, error) {
|
||||
// if _, err := io.WriteString(w, writeHeader); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return &Writer{w}, nil
|
||||
// }
|
||||
|
||||
func (w *Writer) WriteChunk(length int32, typ string, r io.Reader) error {
|
||||
if err := binary.Write(w.w, binary.BigEndian, length); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.w.Write([]byte(typ)); err != nil {
|
||||
return err
|
||||
}
|
||||
checksummer := crc32.NewIEEE()
|
||||
checksummer.Write([]byte(typ))
|
||||
if _, err := io.CopyN(io.MultiWriter(w.w, checksummer), r, int64(length)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Write(w.w, binary.BigEndian, checksummer.Sum32()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// func (w *Writer) WriteChunk(length int32, typ string, r io.Reader) error {
|
||||
// if err := binary.Write(w.w, binary.BigEndian, length); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if _, err := w.w.Write([]byte(typ)); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// checksummer := crc32.NewIEEE()
|
||||
// checksummer.Write([]byte(typ))
|
||||
// if _, err := io.CopyN(io.MultiWriter(w.w, checksummer), r, int64(length)); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if err := binary.Write(w.w, binary.BigEndian, checksummer.Sum32()); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func WriteToPng(c *models.CharCardSpec, fpath, outfile string) error {
|
||||
data, err := os.ReadFile(fpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonData, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Base64 encode the JSON data
|
||||
base64Data := base64.StdEncoding.EncodeToString(jsonData)
|
||||
pe := PngEmbed{
|
||||
Key: cKey,
|
||||
Value: base64Data,
|
||||
}
|
||||
w, err := WritetEXtToPngBytes(data, pe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(outfile, w.Bytes(), 0666)
|
||||
}
|
||||
// func WWriteToPngriteToPng(c *models.CharCardSpec, fpath, outfile string) error {
|
||||
// data, err := os.ReadFile(fpath)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// jsonData, err := json.Marshal(c)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// // Base64 encode the JSON data
|
||||
// base64Data := base64.StdEncoding.EncodeToString(jsonData)
|
||||
// pe := PngEmbed{
|
||||
// Key: cKey,
|
||||
// Value: base64Data,
|
||||
// }
|
||||
// w, err := WritetEXtToPngBytes(data, pe)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return os.WriteFile(outfile, w.Bytes(), 0666)
|
||||
// }
|
||||
|
||||
func WritetEXtToPngBytes(inputBytes []byte, pe PngEmbed) (outputBytes bytes.Buffer, err error) {
|
||||
if !(string(inputBytes[:8]) == header) {
|
||||
return outputBytes, errors.New("wrong file format")
|
||||
}
|
||||
reader := bytes.NewReader(inputBytes)
|
||||
pngr, err := NewPNGStepReader(reader)
|
||||
if err != nil {
|
||||
return outputBytes, fmt.Errorf("NewReader(): %s", err)
|
||||
}
|
||||
pngw, err := NewPNGWriter(&outputBytes)
|
||||
if err != nil {
|
||||
return outputBytes, fmt.Errorf("NewWriter(): %s", err)
|
||||
}
|
||||
for {
|
||||
chunk, err := pngr.Next()
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
return outputBytes, fmt.Errorf("NextChunk(): %s", err)
|
||||
}
|
||||
if chunk.Type() != embType {
|
||||
// IENDChunkType will only appear on the final iteration of a valid PNG
|
||||
if chunk.Type() == IEND {
|
||||
// This is where we inject tEXtChunkType as the penultimate chunk with the new value
|
||||
newtEXtChunk := []byte(fmt.Sprintf(tEXtChunkDataSpecification, pe.Key, pe.Value))
|
||||
if err := pngw.WriteChunk(int32(len(newtEXtChunk)), embType, bytes.NewBuffer(newtEXtChunk)); err != nil {
|
||||
return outputBytes, fmt.Errorf("WriteChunk(): %s", err)
|
||||
}
|
||||
// Now we end the buffer with IENDChunkType chunk
|
||||
if err := pngw.WriteChunk(chunk.length, chunk.Type(), chunk); err != nil {
|
||||
return outputBytes, fmt.Errorf("WriteChunk(): %s", err)
|
||||
}
|
||||
} else {
|
||||
// writes back original chunk to buffer
|
||||
if err := pngw.WriteChunk(chunk.length, chunk.Type(), chunk); err != nil {
|
||||
return outputBytes, fmt.Errorf("WriteChunk(): %s", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if _, err := io.Copy(io.Discard, chunk); err != nil {
|
||||
return outputBytes, fmt.Errorf("io.Copy(io.Discard, chunk): %s", err)
|
||||
}
|
||||
}
|
||||
if err := chunk.Close(); err != nil {
|
||||
return outputBytes, fmt.Errorf("chunk.Close(): %s", err)
|
||||
}
|
||||
}
|
||||
return outputBytes, nil
|
||||
}
|
||||
// func WritetEXtToPngBytes(inputBytes []byte, pe PngEmbed) (outputBytes bytes.Buffer, err error) {
|
||||
// if !(string(inputBytes[:8]) == header) {
|
||||
// return outputBytes, errors.New("wrong file format")
|
||||
// }
|
||||
// reader := bytes.NewReader(inputBytes)
|
||||
// pngr, err := NewPNGStepReader(reader)
|
||||
// if err != nil {
|
||||
// return outputBytes, fmt.Errorf("NewReader(): %s", err)
|
||||
// }
|
||||
// pngw, err := NewPNGWriter(&outputBytes)
|
||||
// if err != nil {
|
||||
// return outputBytes, fmt.Errorf("NewWriter(): %s", err)
|
||||
// }
|
||||
// for {
|
||||
// chunk, err := pngr.Next()
|
||||
// if err != nil {
|
||||
// if errors.Is(err, io.EOF) {
|
||||
// break
|
||||
// }
|
||||
// return outputBytes, fmt.Errorf("NextChunk(): %s", err)
|
||||
// }
|
||||
// if chunk.Type() != embType {
|
||||
// // IENDChunkType will only appear on the final iteration of a valid PNG
|
||||
// if chunk.Type() == IEND {
|
||||
// // This is where we inject tEXtChunkType as the penultimate chunk with the new value
|
||||
// newtEXtChunk := []byte(fmt.Sprintf(tEXtChunkDataSpecification, pe.Key, pe.Value))
|
||||
// if err := pngw.WriteChunk(int32(len(newtEXtChunk)), embType, bytes.NewBuffer(newtEXtChunk)); err != nil {
|
||||
// return outputBytes, fmt.Errorf("WriteChunk(): %s", err)
|
||||
// }
|
||||
// // Now we end the buffer with IENDChunkType chunk
|
||||
// if err := pngw.WriteChunk(chunk.length, chunk.Type(), chunk); err != nil {
|
||||
// return outputBytes, fmt.Errorf("WriteChunk(): %s", err)
|
||||
// }
|
||||
// } else {
|
||||
// // writes back original chunk to buffer
|
||||
// if err := pngw.WriteChunk(chunk.length, chunk.Type(), chunk); err != nil {
|
||||
// return outputBytes, fmt.Errorf("WriteChunk(): %s", err)
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if _, err := io.Copy(io.Discard, chunk); err != nil {
|
||||
// return outputBytes, fmt.Errorf("io.Copy(io.Discard, chunk): %s", err)
|
||||
// }
|
||||
// }
|
||||
// if err := chunk.Close(); err != nil {
|
||||
// return outputBytes, fmt.Errorf("chunk.Close(): %s", err)
|
||||
// }
|
||||
// }
|
||||
// return outputBytes, nil
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user