mirror of
https://github.com/gen2brain/cbconvert
synced 2026-06-30 09:11:54 +02:00
Add Lossless option
This commit is contained in:
@@ -27,6 +27,8 @@ type Options struct {
|
|||||||
Quality int
|
Quality int
|
||||||
// Encoder speed/effort, format-specific: webp method 0-6, avif speed 0-10, jxl effort 1-10; -1 uses the format default
|
// Encoder speed/effort, format-specific: webp method 0-6, avif speed 0-10, jxl effort 1-10; -1 uses the format default
|
||||||
Effort int
|
Effort int
|
||||||
|
// Lossless enables lossless compression (webp, avif, jxl), ignores quality
|
||||||
|
Lossless bool
|
||||||
// Image width
|
// Image width
|
||||||
Width int
|
Width int
|
||||||
// Image height
|
// Image height
|
||||||
|
|||||||
@@ -402,19 +402,19 @@ func (c *Converter) imageEncode(img image.Image, w io.Writer) error {
|
|||||||
if c.Opts.Effort >= 0 {
|
if c.Opts.Effort >= 0 {
|
||||||
method = min(max(c.Opts.Effort, 0), 6)
|
method = min(max(c.Opts.Effort, 0), 6)
|
||||||
}
|
}
|
||||||
err = webp.Encode(w, img, webp.Options{Quality: c.Opts.Quality, Method: method})
|
err = webp.Encode(w, img, webp.Options{Quality: c.Opts.Quality, Method: method, Lossless: c.Opts.Lossless})
|
||||||
case "avif":
|
case "avif":
|
||||||
speed := avif.DefaultSpeed
|
speed := avif.DefaultSpeed
|
||||||
if c.Opts.Effort >= 0 {
|
if c.Opts.Effort >= 0 {
|
||||||
speed = min(max(c.Opts.Effort, 0), 10)
|
speed = min(max(c.Opts.Effort, 0), 10)
|
||||||
}
|
}
|
||||||
err = avif.Encode(w, img, avif.Options{Quality: c.Opts.Quality, Speed: speed})
|
err = avif.Encode(w, img, avif.Options{Quality: c.Opts.Quality, Speed: speed, Lossless: c.Opts.Lossless})
|
||||||
case "jxl":
|
case "jxl":
|
||||||
effort := jpegxl.DefaultEffort
|
effort := jpegxl.DefaultEffort
|
||||||
if c.Opts.Effort >= 0 {
|
if c.Opts.Effort >= 0 {
|
||||||
effort = min(max(c.Opts.Effort, 1), 10)
|
effort = min(max(c.Opts.Effort, 1), 10)
|
||||||
}
|
}
|
||||||
err = jpegxl.Encode(w, img, jpegxl.Options{Quality: c.Opts.Quality, Effort: effort})
|
err = jpegxl.Encode(w, img, jpegxl.Options{Quality: c.Opts.Quality, Effort: effort, Lossless: c.Opts.Lossless})
|
||||||
case "bmp":
|
case "bmp":
|
||||||
opts := &gobmp.EncoderOptions{}
|
opts := &gobmp.EncoderOptions{}
|
||||||
opts.SupportTransparency(false)
|
opts.SupportTransparency(false)
|
||||||
|
|||||||
+101
-61
@@ -146,6 +146,7 @@ func options() cbconvert.Options {
|
|||||||
default:
|
default:
|
||||||
opts.Effort = -1
|
opts.Effort = -1
|
||||||
}
|
}
|
||||||
|
opts.Lossless = iup.GetHandle("Lossless").GetAttribute("VALUE") == "ON"
|
||||||
opts.Grayscale = iup.GetHandle("Grayscale").GetAttribute("VALUE") == "ON"
|
opts.Grayscale = iup.GetHandle("Grayscale").GetAttribute("VALUE") == "ON"
|
||||||
opts.Brightness = iup.GetHandle("Brightness").GetInt("VALUE")
|
opts.Brightness = iup.GetHandle("Brightness").GetInt("VALUE")
|
||||||
opts.Contrast = iup.GetHandle("Contrast").GetInt("VALUE")
|
opts.Contrast = iup.GetHandle("Contrast").GetInt("VALUE")
|
||||||
@@ -171,24 +172,30 @@ func setActive() {
|
|||||||
iup.GetHandle("RemoveAll").SetAttribute("ACTIVE", "YES")
|
iup.GetHandle("RemoveAll").SetAttribute("ACTIVE", "YES")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.OutDir == "" {
|
active := "YES"
|
||||||
iup.GetHandle("Thumbnail").SetAttributes(`ACTIVE=NO`)
|
var tip string
|
||||||
iup.GetHandle("Cover").SetAttributes(`ACTIVE=NO`)
|
switch {
|
||||||
iup.GetHandle("Convert").SetAttributes(`ACTIVE=NO`)
|
case count == 0 && opts.OutDir == "":
|
||||||
if count > 0 {
|
active, tip = "NO", "Add files and set output directory"
|
||||||
iup.GetHandle("Thumbnail").SetAttributes(`ACTIVE=NO, TIP="Set Output Directory"`)
|
case count == 0:
|
||||||
iup.GetHandle("Cover").SetAttributes(`ACTIVE=NO, TIP="Set Output Directory"`)
|
active, tip = "NO", "Add files"
|
||||||
iup.GetHandle("Convert").SetAttributes(`ACTIVE=NO, TIP="Set Output Directory"`)
|
case opts.OutDir == "":
|
||||||
|
active, tip = "NO", "Set output directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enabledTip := map[string]string{
|
||||||
|
"Thumbnail": "Extract cover thumbnails",
|
||||||
|
"Cover": "Extract covers",
|
||||||
|
"Convert": "Convert files to the selected format",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range []string{"Thumbnail", "Cover", "Convert"} {
|
||||||
|
b := iup.GetHandle(h)
|
||||||
|
b.SetAttribute("ACTIVE", active)
|
||||||
|
if active == "YES" {
|
||||||
|
b.SetAttribute("TIP", enabledTip[h])
|
||||||
} else {
|
} else {
|
||||||
if count > 0 {
|
b.SetAttribute("TIP", tip)
|
||||||
iup.GetHandle("Thumbnail").SetAttributes(`ACTIVE=YES, TIP=""`)
|
|
||||||
iup.GetHandle("Cover").SetAttributes(`ACTIVE=YES, TIP=""`)
|
|
||||||
iup.GetHandle("Convert").SetAttributes(`ACTIVE=YES, TIP=""`)
|
|
||||||
} else {
|
|
||||||
iup.GetHandle("Thumbnail").SetAttributes(`ACTIVE=NO`)
|
|
||||||
iup.GetHandle("Cover").SetAttributes(`ACTIVE=NO`)
|
|
||||||
iup.GetHandle("Convert").SetAttributes(`ACTIVE=NO`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,16 +207,21 @@ func setActive() {
|
|||||||
iup.GetHandle("VboxTransform").SetAttribute("ACTIVE", "YES")
|
iup.GetHandle("VboxTransform").SetAttribute("ACTIVE", "YES")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.Format == "jpeg" || opts.Format == "webp" || opts.Format == "avif" || opts.Format == "jxl") && !opts.NoConvert {
|
canLossless := opts.Format == "webp" || opts.Format == "avif" || opts.Format == "jxl"
|
||||||
|
losslessOn := canLossless && opts.Lossless
|
||||||
|
|
||||||
|
if (opts.Format == "jpeg" || canLossless) && !opts.NoConvert && !losslessOn {
|
||||||
iup.GetHandle("VboxQuality").SetAttribute("ACTIVE", "YES")
|
iup.GetHandle("VboxQuality").SetAttribute("ACTIVE", "YES")
|
||||||
} else {
|
} else {
|
||||||
iup.GetHandle("VboxQuality").SetAttribute("ACTIVE", "NO")
|
iup.GetHandle("VboxQuality").SetAttribute("ACTIVE", "NO")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.Format == "webp" || opts.Format == "avif" || opts.Format == "jxl") && !opts.NoConvert {
|
if canLossless && !opts.NoConvert {
|
||||||
iup.GetHandle("VboxEffort").SetAttribute("ACTIVE", "YES")
|
iup.GetHandle("VboxEffort").SetAttribute("ACTIVE", "YES")
|
||||||
|
iup.GetHandle("Lossless").SetAttribute("ACTIVE", "YES")
|
||||||
} else {
|
} else {
|
||||||
iup.GetHandle("VboxEffort").SetAttribute("ACTIVE", "NO")
|
iup.GetHandle("VboxEffort").SetAttribute("ACTIVE", "NO")
|
||||||
|
iup.GetHandle("Lossless").SetAttribute("ACTIVE", "NO")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Width != 0 && opts.Height != 0 && !opts.NoConvert {
|
if opts.Width != 0 && opts.Height != 0 && !opts.NoConvert {
|
||||||
@@ -243,6 +255,7 @@ func setEffort(format string) {
|
|||||||
|
|
||||||
val.SetAttribute("EFFORTNAME", name)
|
val.SetAttribute("EFFORTNAME", name)
|
||||||
iup.GetHandle("LabelEffort").SetAttribute("TITLE", fmt.Sprintf("%s: %d", name, val.GetInt("VALUE")))
|
iup.GetHandle("LabelEffort").SetAttribute("TITLE", fmt.Sprintf("%s: %d", name, val.GetInt("VALUE")))
|
||||||
|
iup.Refresh(iup.GetHandle("LabelEffort"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func layout() iup.Ihandle {
|
func layout() iup.Ihandle {
|
||||||
@@ -401,7 +414,7 @@ func tabs() iup.Ihandle {
|
|||||||
SetAttributes(`TIP="Process only files larger than minimum size"`),
|
SetAttributes(`TIP="Process only files larger than minimum size"`),
|
||||||
),
|
),
|
||||||
iup.Space().SetAttributes("EXPAND=HORIZONTAL"),
|
iup.Space().SetAttributes("EXPAND=HORIZONTAL"),
|
||||||
).SetHandle("VboxInput").SetAttributes("MARGIN=5x5, GAP=5")
|
).SetHandle("VboxInput").SetAttributes("NGAP=10")
|
||||||
|
|
||||||
vboxOutput := iup.Vbox(
|
vboxOutput := iup.Vbox(
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
@@ -430,9 +443,10 @@ func tabs() iup.Ihandle {
|
|||||||
"2": "TAR",
|
"2": "TAR",
|
||||||
}).SetHandle("Archive"),
|
}).SetHandle("Archive"),
|
||||||
),
|
),
|
||||||
).SetHandle("VboxOutput").SetAttributes("MARGIN=5x5, GAP=5")
|
).SetHandle("VboxOutput").SetAttributes("NGAP=10")
|
||||||
|
|
||||||
vboxImage := iup.Vbox(
|
vboxImage := iup.Hbox(
|
||||||
|
iup.Vbox(
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Label("Format:"),
|
iup.Label("Format:"),
|
||||||
iup.List().SetAttributes(map[string]string{
|
iup.List().SetAttributes(map[string]string{
|
||||||
@@ -457,7 +471,7 @@ func tabs() iup.Ihandle {
|
|||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Label("Size:"),
|
iup.Label("Size:"),
|
||||||
iup.Hbox(
|
iup.Hbox(
|
||||||
iup.Text().SetAttributes(`CUEBANNER=" width", VISIBLECOLUMNS=4, MASK="/d*"`).SetHandle("Width").
|
iup.Text().SetAttributes(`CUEBANNER="width", VISIBLECOLUMNS=6, MASK="/d*"`).SetHandle("Width").
|
||||||
SetAttribute("TIP", "If one of, width or height is not set, the image aspect ratio is preserved").
|
SetAttribute("TIP", "If one of, width or height is not set, the image aspect ratio is preserved").
|
||||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
setActive()
|
setActive()
|
||||||
@@ -473,8 +487,10 @@ func tabs() iup.Ihandle {
|
|||||||
|
|
||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
})),
|
})),
|
||||||
|
iup.Space().SetAttribute("SIZE", "2"),
|
||||||
iup.Label("x"),
|
iup.Label("x"),
|
||||||
iup.Text().SetAttributes(`CUEBANNER=" height", VISIBLECOLUMNS=4, MASK="/d*"`).SetHandle("Height").
|
iup.Space().SetAttribute("SIZE", "2"),
|
||||||
|
iup.Text().SetAttributes(`CUEBANNER="height", VISIBLECOLUMNS=6, MASK="/d*"`).SetHandle("Height").
|
||||||
SetAttribute("TIP", "If one of, width or height is not set, the image aspect ratio is preserved").
|
SetAttribute("TIP", "If one of, width or height is not set, the image aspect ratio is preserved").
|
||||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
setActive()
|
setActive()
|
||||||
@@ -490,7 +506,7 @@ func tabs() iup.Ihandle {
|
|||||||
|
|
||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
})),
|
})),
|
||||||
).SetAttributes("ALIGNMENT=ACENTER, MARGIN=0"),
|
).SetAttributes("ALIGNMENT=ACENTER, NMARGIN=0"),
|
||||||
),
|
),
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Toggle(" Best Fit").SetHandle("Fit").
|
iup.Toggle(" Best Fit").SetHandle("Fit").
|
||||||
@@ -511,15 +527,19 @@ func tabs() iup.Ihandle {
|
|||||||
"7": "Lanczos",
|
"7": "Lanczos",
|
||||||
}).SetHandle("Filter").SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(onFilterChanged)),
|
}).SetHandle("Filter").SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(onFilterChanged)),
|
||||||
),
|
),
|
||||||
|
).SetAttributes("NGAP=10"),
|
||||||
|
iup.Space().SetAttribute("SIZE", "15"),
|
||||||
|
iup.Vbox(
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Hbox(
|
iup.Hbox(
|
||||||
iup.Label("Quality: "),
|
iup.Label("Quality: "),
|
||||||
iup.Label("75").SetHandle("LabelQuality"),
|
iup.Label("75").SetHandle("LabelQuality"),
|
||||||
).SetAttributes("MARGIN=0"),
|
).SetAttributes("NMARGIN=0"),
|
||||||
iup.Val("").SetAttributes(`MIN=0, MAX=100, VALUE=75, SHOWTICKS=10`).SetHandle("Quality").
|
iup.Val("").SetAttributes(`MIN=0, MAX=100, VALUE=75, SHOWTICKS=10`).SetHandle("Quality").
|
||||||
SetAttribute("TIP", "Quality affects JPEG, WEBP, AVIF and JXL").
|
SetAttribute("TIP", "Quality affects JPEG, WEBP, AVIF and JXL").
|
||||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
iup.GetHandle("LabelQuality").SetAttribute("TITLE", ih.GetInt("VALUE"))
|
iup.GetHandle("LabelQuality").SetAttribute("TITLE", ih.GetInt("VALUE"))
|
||||||
|
iup.Refresh(iup.GetHandle("LabelQuality"))
|
||||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||||
|
|
||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
@@ -534,11 +554,12 @@ func tabs() iup.Ihandle {
|
|||||||
})),
|
})),
|
||||||
).SetHandle("VboxQuality"),
|
).SetHandle("VboxQuality"),
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Label("").SetHandle("LabelEffort"),
|
iup.Label("Effort:").SetHandle("LabelEffort"),
|
||||||
iup.Val("").SetAttributes(`MIN=0, MAX=10, VALUE=0, SHOWTICKS=11`).SetHandle("Effort").
|
iup.Val("").SetAttributes(`MIN=0, MAX=10, VALUE=0, SHOWTICKS=11`).SetHandle("Effort").
|
||||||
SetAttribute("TIP", "Encoder speed/effort (WEBP, AVIF, JXL)").
|
SetAttribute("TIP", "Encoder speed/effort (WEBP, AVIF, JXL)").
|
||||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
iup.GetHandle("LabelEffort").SetAttribute("TITLE", fmt.Sprintf("%s: %d", ih.GetAttribute("EFFORTNAME"), ih.GetInt("VALUE")))
|
iup.GetHandle("LabelEffort").SetAttribute("TITLE", fmt.Sprintf("%s: %d", ih.GetAttribute("EFFORTNAME"), ih.GetInt("VALUE")))
|
||||||
|
iup.Refresh(iup.GetHandle("LabelEffort"))
|
||||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||||
|
|
||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
@@ -552,6 +573,16 @@ func tabs() iup.Ihandle {
|
|||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
})),
|
})),
|
||||||
).SetHandle("VboxEffort"),
|
).SetHandle("VboxEffort"),
|
||||||
|
iup.Vbox(
|
||||||
|
iup.Toggle(" Lossless").SetHandle("Lossless").
|
||||||
|
SetAttributes(`TIP="Lossless compression (WEBP, AVIF, JXL), ignores quality"`).
|
||||||
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
|
setActive()
|
||||||
|
previewPost()
|
||||||
|
|
||||||
|
return iup.DEFAULT
|
||||||
|
})),
|
||||||
|
),
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Toggle(" Grayscale").SetHandle("Grayscale").
|
iup.Toggle(" Grayscale").SetHandle("Grayscale").
|
||||||
SetAttributes(`TIP="Convert images to grayscale (monochromatic)"`).
|
SetAttributes(`TIP="Convert images to grayscale (monochromatic)"`).
|
||||||
@@ -561,18 +592,20 @@ func tabs() iup.Ihandle {
|
|||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
).SetHandle("VboxImage").SetAttributes("MARGIN=5x5, GAP=5")
|
).SetAttributes("NGAP=10"),
|
||||||
|
).SetHandle("VboxImage")
|
||||||
|
|
||||||
vboxTransform := iup.Vbox(
|
vboxTransform := iup.Vbox(
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Hbox(
|
iup.Hbox(
|
||||||
iup.Label("Brightness: "),
|
iup.Label("Brightness: "),
|
||||||
iup.Label("0").SetHandle("LabelBrightness"),
|
iup.Label("0").SetHandle("LabelBrightness"),
|
||||||
).SetAttributes("ALIGNMENT=ACENTER, MARGIN=0"),
|
).SetAttributes("ALIGNMENT=ACENTER, NMARGIN=0"),
|
||||||
iup.Val("").SetAttributes(`MIN=-100, MAX=100, VALUE=0, SHOWTICKS=10`).SetHandle("Brightness").
|
iup.Val("").SetAttributes(`MIN=-100, MAX=100, VALUE=0, SHOWTICKS=10`).SetHandle("Brightness").
|
||||||
SetAttributes(`TIP="Adjust the brightness of the images"`).
|
SetAttributes(`TIP="Adjust the brightness of the images"`).
|
||||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
iup.GetHandle("LabelBrightness").SetAttribute("TITLE", iup.GetHandle("Brightness").GetInt("VALUE"))
|
iup.GetHandle("LabelBrightness").SetAttribute("TITLE", iup.GetHandle("Brightness").GetInt("VALUE"))
|
||||||
|
iup.Refresh(iup.GetHandle("LabelBrightness"))
|
||||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||||
|
|
||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
@@ -590,11 +623,12 @@ func tabs() iup.Ihandle {
|
|||||||
iup.Hbox(
|
iup.Hbox(
|
||||||
iup.Label("Contrast: "),
|
iup.Label("Contrast: "),
|
||||||
iup.Label("0").SetHandle("LabelContrast"),
|
iup.Label("0").SetHandle("LabelContrast"),
|
||||||
).SetAttributes("ALIGNMENT=ACENTER, MARGIN=0"),
|
).SetAttributes("ALIGNMENT=ACENTER, NMARGIN=0"),
|
||||||
iup.Val("").SetAttributes(`MIN=-100, MAX=100, VALUE=0, SHOWTICKS=10`).SetHandle("Contrast").
|
iup.Val("").SetAttributes(`MIN=-100, MAX=100, VALUE=0, SHOWTICKS=10`).SetHandle("Contrast").
|
||||||
SetAttributes(`TIP="Adjust the contrast of the images"`).
|
SetAttributes(`TIP="Adjust the contrast of the images"`).
|
||||||
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
SetCallback("VALUECHANGED_CB", iup.ValueChangedFunc(func(ih iup.Ihandle) int {
|
||||||
iup.GetHandle("LabelContrast").SetAttribute("TITLE", iup.GetHandle("Contrast").GetInt("VALUE"))
|
iup.GetHandle("LabelContrast").SetAttribute("TITLE", iup.GetHandle("Contrast").GetInt("VALUE"))
|
||||||
|
iup.Refresh(iup.GetHandle("LabelContrast"))
|
||||||
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
ih.SetAttribute("MYVALUE", ih.GetInt("VALUE"))
|
||||||
|
|
||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
@@ -624,45 +658,51 @@ func tabs() iup.Ihandle {
|
|||||||
return iup.DEFAULT
|
return iup.DEFAULT
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
).SetHandle("VboxTransform").SetAttributes("MARGIN=5x5, GAP=5")
|
).SetHandle("VboxTransform").SetAttributes("NGAP=10")
|
||||||
|
|
||||||
return iup.Tabs(
|
return iup.Tabs(
|
||||||
vboxInput.SetAttributes("TABTITLE=Input"),
|
vboxInput.SetAttributes("TABTITLE=Input, NMARGIN=10x10"),
|
||||||
vboxOutput.SetAttributes("TABTITLE=Output"),
|
vboxOutput.SetAttributes("TABTITLE=Output, NMARGIN=10x10"),
|
||||||
vboxImage.SetAttributes("TABTITLE=Image"),
|
vboxImage.SetAttributes("TABTITLE=Image, NMARGIN=10x10"),
|
||||||
vboxTransform.SetAttributes("TABTITLE=Transform"),
|
vboxTransform.SetAttributes("TABTITLE=Transform, NMARGIN=10x10"),
|
||||||
).SetHandle("Tabs").SetAttributes("MINSIZE=320x400, EXPAND=HORIZONTAL, MULTILINE=YES")
|
).SetHandle("Tabs")
|
||||||
}
|
}
|
||||||
|
|
||||||
func buttons() iup.Ihandle {
|
func buttons() iup.Ihandle {
|
||||||
|
addFiles := iup.Button("Add &Files...").SetHandle("AddFiles").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onAddFiles))
|
||||||
|
addDir := iup.Button("Add &Dir...").SetHandle("AddDir").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onAddDir))
|
||||||
|
remove := iup.Button("Remove").SetHandle("Remove").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onRemove))
|
||||||
|
removeAll := iup.Button("Remove All").SetHandle("RemoveAll").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onRemoveAll))
|
||||||
|
thumbnail := iup.Button("Thumbnail").SetHandle("Thumbnail").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onThumbnail))
|
||||||
|
cover := iup.Button("Cover").SetHandle("Cover").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onCover))
|
||||||
|
convert := iup.Button("&Convert").SetHandle("Convert").SetAttributes("PADDING=DEFAULTBUTTONPADDING").
|
||||||
|
SetCallback("ACTION", iup.ActionFunc(onConvert))
|
||||||
|
|
||||||
|
iup.Normalizer(addFiles, addDir, remove, removeAll, thumbnail, cover, convert).SetAttribute("NORMALIZE", "BOTH")
|
||||||
|
|
||||||
return iup.Vbox(
|
return iup.Vbox(
|
||||||
iup.Frame(
|
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Button("Add &Files...").SetHandle("AddFiles").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
addFiles,
|
||||||
SetCallback("ACTION", iup.ActionFunc(onAddFiles)),
|
addDir,
|
||||||
iup.Button("Add &Dir...").SetHandle("AddDir").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
remove,
|
||||||
SetCallback("ACTION", iup.ActionFunc(onAddDir)),
|
removeAll,
|
||||||
iup.Button("Remove").SetHandle("Remove").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
).SetAttribute("NGAP", "2"),
|
||||||
SetCallback("ACTION", iup.ActionFunc(onRemove)),
|
iup.Space().SetAttribute("SIZE", "x5"),
|
||||||
iup.Button("Remove All").SetHandle("RemoveAll").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
|
||||||
SetCallback("ACTION", iup.ActionFunc(onRemoveAll)),
|
|
||||||
).SetAttributes("NGAP=5"),
|
|
||||||
),
|
|
||||||
iup.Frame(
|
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Button("Thumbnail").SetHandle("Thumbnail").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
thumbnail,
|
||||||
SetCallback("ACTION", iup.ActionFunc(onThumbnail)),
|
cover,
|
||||||
iup.Button("Cover").SetHandle("Cover").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
).SetAttribute("NGAP", "2"),
|
||||||
SetCallback("ACTION", iup.ActionFunc(onCover)),
|
iup.Space().SetAttribute("SIZE", "x5"),
|
||||||
).SetAttributes("NGAP=5"),
|
|
||||||
),
|
|
||||||
iup.Frame(
|
|
||||||
iup.Vbox(
|
iup.Vbox(
|
||||||
iup.Button("&Convert").SetHandle("Convert").SetAttributes("EXPAND=HORIZONTAL, PADDING=DEFAULTBUTTONPADDING").
|
convert,
|
||||||
SetCallback("ACTION", iup.ActionFunc(onConvert)),
|
|
||||||
),
|
),
|
||||||
),
|
).SetHandle("Buttons").SetAttributes("ALIGNMENT=ACENTER")
|
||||||
).SetHandle("Buttons").SetAttributes("ALIGNMENT=ACENTER, NGAP=10")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func status() iup.Ihandle {
|
func status() iup.Ihandle {
|
||||||
@@ -670,10 +710,10 @@ func status() iup.Ihandle {
|
|||||||
loading(),
|
loading(),
|
||||||
iup.Fill(),
|
iup.Fill(),
|
||||||
iup.Label("File 1 of 1").SetHandle("LabelStatus1").SetAttributes("VISIBLE=NO"),
|
iup.Label("File 1 of 1").SetHandle("LabelStatus1").SetAttributes("VISIBLE=NO"),
|
||||||
iup.Space().SetAttribute("SIZE", "5x0"),
|
iup.Space().SetAttribute("SIZE", "5"),
|
||||||
iup.Label("(000/000)").SetHandle("LabelStatus2").SetAttributes("VISIBLE=NO"),
|
iup.Label("(000/000)").SetHandle("LabelStatus2").SetAttributes("VISIBLE=NO"),
|
||||||
iup.Space().SetAttribute("SIZE", "5x0"),
|
iup.Space().SetAttribute("SIZE", "5"),
|
||||||
iup.ProgressBar().SetAttributes("RASTERSIZE=200x15, VISIBLE=NO").SetHandle("ProgressBar").
|
iup.ProgressBar().SetAttributes("RASTERSIZE=200x, VISIBLE=NO").SetHandle("ProgressBar").
|
||||||
SetCallback("POSTMESSAGE_CB", iup.PostMessageFunc(func(ih iup.Ihandle, s string, i int, p any) int {
|
SetCallback("POSTMESSAGE_CB", iup.PostMessageFunc(func(ih iup.Ihandle, s string, i int, p any) int {
|
||||||
switch s {
|
switch s {
|
||||||
case "convert":
|
case "convert":
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
convert.StringVar(&opts.Archive, "archive", "zip", "Archive format, valid values are zip, tar")
|
convert.StringVar(&opts.Archive, "archive", "zip", "Archive format, valid values are zip, tar")
|
||||||
convert.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
convert.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
||||||
convert.IntVar(&opts.Effort, "effort", -1, "Encoder speed/effort, format-specific (webp method 0-6, avif speed 0-10, jxl effort 1-10), -1 uses the format default")
|
convert.IntVar(&opts.Effort, "effort", -1, "Encoder speed/effort, format-specific (webp method 0-6, avif speed 0-10, jxl effort 1-10), -1 uses the format default")
|
||||||
|
convert.BoolVar(&opts.Lossless, "lossless", false, "Lossless compression (webp, avif, jxl), ignores quality")
|
||||||
convert.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
convert.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
||||||
convert.BoolVar(&opts.NoCover, "no-cover", false, "Do not convert the cover image")
|
convert.BoolVar(&opts.NoCover, "no-cover", false, "Do not convert the cover image")
|
||||||
convert.BoolVar(&opts.NoRGB, "no-rgb", false, "Do not convert images that have RGB colorspace")
|
convert.BoolVar(&opts.NoRGB, "no-rgb", false, "Do not convert images that have RGB colorspace")
|
||||||
@@ -190,6 +191,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
cover.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif")
|
cover.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif")
|
||||||
cover.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
cover.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
||||||
cover.IntVar(&opts.Effort, "effort", -1, "Encoder speed/effort, format-specific (webp method 0-6, avif speed 0-10, jxl effort 1-10), -1 uses the format default")
|
cover.IntVar(&opts.Effort, "effort", -1, "Encoder speed/effort, format-specific (webp method 0-6, avif speed 0-10, jxl effort 1-10), -1 uses the format default")
|
||||||
|
cover.BoolVar(&opts.Lossless, "lossless", false, "Lossless compression (webp, avif, jxl), ignores quality")
|
||||||
cover.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
cover.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
||||||
cover.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
cover.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
||||||
cover.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
|
cover.IntVar(&opts.Size, "size", 0, "Process only files larger than size (in MB)")
|
||||||
@@ -220,7 +222,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
|
fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
|
||||||
fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
||||||
fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
|
fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
|
||||||
order := []string{"width", "height", "fit", "format", "archive", "quality", "effort", "filter", "no-cover", "no-rgb",
|
order := []string{"width", "height", "fit", "format", "archive", "quality", "effort", "lossless", "filter", "no-cover", "no-rgb",
|
||||||
"no-nonimage", "no-convert", "grayscale", "rotate", "brightness", "contrast", "suffix", "outdir", "size", "recursive", "quiet"}
|
"no-nonimage", "no-convert", "grayscale", "rotate", "brightness", "contrast", "suffix", "outdir", "size", "recursive", "quiet"}
|
||||||
for _, name := range order {
|
for _, name := range order {
|
||||||
f := convert.Lookup(name)
|
f := convert.Lookup(name)
|
||||||
@@ -228,7 +230,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
|||||||
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
|
fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
|
||||||
order = []string{"width", "height", "fit", "format", "quality", "effort", "filter", "outdir", "size", "recursive", "quiet"}
|
order = []string{"width", "height", "fit", "format", "quality", "effort", "lossless", "filter", "outdir", "size", "recursive", "quiet"}
|
||||||
for _, name := range order {
|
for _, name := range order {
|
||||||
f := cover.Lookup(name)
|
f := cover.Lookup(name)
|
||||||
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||||
|
|||||||
Reference in New Issue
Block a user