summaryrefslogtreecommitdiff
path: root/internal/comic/image_validation.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/comic/image_validation.go')
-rw-r--r--internal/comic/image_validation.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/internal/comic/image_validation.go b/internal/comic/image_validation.go
new file mode 100644
index 0000000..475cb96
--- /dev/null
+++ b/internal/comic/image_validation.go
@@ -0,0 +1,68 @@
+package comic
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "os/exec"
+ "strings"
+)
+
+var imageLeakMarkers = []string{
+ "mandatory language rule",
+ "this is a bulgarian comic book",
+ "bulgarian comic book",
+ "mandatory panel layout",
+ "mandatory speech bubbles",
+ "ultra-realistic rendering",
+ "final lock",
+ "photorealism",
+ "character & setting reference",
+ "this is a text-free character gallery page",
+ "story page",
+ "gallery page",
+ "back cover",
+ "cover lines",
+ "story teaser",
+ "story ending hint",
+ "art style:",
+ "no panel grid",
+ "no speech bubbles",
+ "no text of any kind",
+}
+
+var validateImagePromptLeakageFn = validateImagePromptLeakage
+
+func validateImagePromptLeakage(ctx context.Context, outputFile, label string) error {
+ if ctx == nil {
+ ctx = context.Background()
+ }
+
+ tesseractPath, err := exec.LookPath("tesseract")
+ if err != nil {
+ return nil
+ }
+
+ cmd := exec.CommandContext(ctx, tesseractPath, outputFile, "stdout", "-l", "eng", "--psm", "11")
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ cmd.Stderr = &bytes.Buffer{}
+ if err := cmd.Run(); err != nil {
+ return fmt.Errorf("%s OCR failed: %w", label, err)
+ }
+
+ ocr := strings.ToLower(out.String())
+ if marker, ok := findImageLeakMarker(ocr); ok {
+ return fmt.Errorf("%s contains prompt leakage marker %q", label, marker)
+ }
+ return nil
+}
+
+func findImageLeakMarker(text string) (string, bool) {
+ for _, marker := range imageLeakMarkers {
+ if strings.Contains(text, marker) {
+ return marker, true
+ }
+ }
+ return "", false
+}