Shalmoni commited on
Commit
c4bcf4f
·
verified ·
1 Parent(s): 0a73965

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -13
app.py CHANGED
@@ -34,6 +34,21 @@ def pil_to_b64(img_pil: Image.Image) -> str:
34
  img_pil.save(buf, format="PNG")
35
  return base64.b64encode(buf.getvalue()).decode("utf-8")
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  def build_prompt(user_text: str, is_first: bool, lock_longshot: bool = True) -> str:
38
  """Compose continuity-aware prompt text."""
39
  user_text = (user_text or "").strip()
@@ -215,15 +230,13 @@ def _poll_and_decode(job_id: str, dbg: list[str]):
215
  dbg.append("No 'img' field present.")
216
  return None, "\n".join(dbg)
217
 
218
- pad = (-len(b64)) % 4
219
- if pad:
220
- b64 = b64 + ("=" * pad)
221
  try:
222
- img_bytes = base64.b64decode(b64, validate=False)
223
- except binascii.Error as e:
224
- dbg.append(f"Base64 decode error: {e}")
 
225
  try:
226
- txt = base64.b64decode(b64 + '==', validate=False).decode("utf-8", "ignore").strip()
227
  if txt.startswith("http"):
228
  r = requests.get(txt, timeout=60)
229
  r.raise_for_status()
@@ -231,7 +244,7 @@ def _poll_and_decode(job_id: str, dbg: list[str]):
231
  else:
232
  return None, "\n".join(dbg)
233
  except Exception as e2:
234
- dbg.append(f"Secondary b64/text parse failed: {type(e2).__name__}: {e2}")
235
  return None, "\n".join(dbg)
236
 
237
  return _decode_bytes_to_image(img_bytes, dbg)
@@ -293,7 +306,8 @@ def generate_next(prompt_text, steps, size, lock, prev_img, change):
293
  w, h = _parse_size(size)
294
  prompt = build_prompt(prompt_text, is_first=False, lock_longshot=lock)
295
  init_img = prev_img if isinstance(prev_img, Image.Image) else None
296
- img, debug = horde_generate(prompt, steps=steps, width=w, height=h, init_image=init_img, denoise=float(change))
 
297
  if img is None:
298
  gr.Warning("Generation failed. See debug log for details.")
299
  return img, debug
@@ -310,7 +324,6 @@ def _parse_size(s):
310
  # =========================
311
  CUSTOM_CSS = """
312
  .gradio-container { padding: 24px; }
313
-
314
  /* Rounded prompt boxes */
315
  .prompt-box textarea {
316
  border-radius: 18px !important;
@@ -319,14 +332,12 @@ CUSTOM_CSS = """
319
  line-height: 1.4;
320
  padding: 14px 16px;
321
  }
322
-
323
  /* Pill buttons */
324
  .pill button {
325
  border-radius: 999px !important;
326
  padding: 10px 18px;
327
  font-size: 15px;
328
  }
329
-
330
  /* Rounded image boxes */
331
  .image-out .wrap, .image-out .svelte-1ipelgc {
332
  border-radius: 22px !important;
@@ -412,4 +423,4 @@ with gr.Blocks(css=CUSTOM_CSS, title="Image Checkpoints – Stable Horde (txt2im
412
 
413
  if __name__ == "__main__":
414
  demo.queue().launch()
415
-
 
34
  img_pil.save(buf, format="PNG")
35
  return base64.b64encode(buf.getvalue()).decode("utf-8")
36
 
37
+ def _b64_to_bytes(s: str) -> bytes:
38
+ """
39
+ Robustly decode base64 / base64url (handles '-' '_' and missing padding).
40
+ """
41
+ s = (s or "").strip()
42
+ s = s.replace("-", "+").replace("_", "/")
43
+ pad = (-len(s)) % 4
44
+ if pad:
45
+ s += "=" * pad
46
+ try:
47
+ return base64.b64decode(s, validate=False)
48
+ except Exception:
49
+ # final fallback using urlsafe decoder
50
+ return base64.urlsafe_b64decode(s + "=" * ((4 - len(s) % 4) % 4))
51
+
52
  def build_prompt(user_text: str, is_first: bool, lock_longshot: bool = True) -> str:
53
  """Compose continuity-aware prompt text."""
54
  user_text = (user_text or "").strip()
 
230
  dbg.append("No 'img' field present.")
231
  return None, "\n".join(dbg)
232
 
 
 
 
233
  try:
234
+ img_bytes = _b64_to_bytes(b64)
235
+ except Exception as e:
236
+ dbg.append(f"Base64/urlsafe decode failed: {type(e).__name__}: {e}")
237
+ # Try interpret as URL text after decode
238
  try:
239
+ txt = _b64_to_bytes(b64).decode("utf-8", "ignore").strip()
240
  if txt.startswith("http"):
241
  r = requests.get(txt, timeout=60)
242
  r.raise_for_status()
 
244
  else:
245
  return None, "\n".join(dbg)
246
  except Exception as e2:
247
+ dbg.append(f"Secondary b64text URL parse failed: {type(e2).__name__}: {e2}")
248
  return None, "\n".join(dbg)
249
 
250
  return _decode_bytes_to_image(img_bytes, dbg)
 
306
  w, h = _parse_size(size)
307
  prompt = build_prompt(prompt_text, is_first=False, lock_longshot=lock)
308
  init_img = prev_img if isinstance(prev_img, Image.Image) else None
309
+ img, debug = horde_generate(prompt, steps=steps, width=w, height=h,
310
+ init_image=init_img, denoise=float(change))
311
  if img is None:
312
  gr.Warning("Generation failed. See debug log for details.")
313
  return img, debug
 
324
  # =========================
325
  CUSTOM_CSS = """
326
  .gradio-container { padding: 24px; }
 
327
  /* Rounded prompt boxes */
328
  .prompt-box textarea {
329
  border-radius: 18px !important;
 
332
  line-height: 1.4;
333
  padding: 14px 16px;
334
  }
 
335
  /* Pill buttons */
336
  .pill button {
337
  border-radius: 999px !important;
338
  padding: 10px 18px;
339
  font-size: 15px;
340
  }
 
341
  /* Rounded image boxes */
342
  .image-out .wrap, .image-out .svelte-1ipelgc {
343
  border-radius: 22px !important;
 
423
 
424
  if __name__ == "__main__":
425
  demo.queue().launch()
426
+