202 lines
7.5 KiB
Python
202 lines
7.5 KiB
Python
import requests
|
|
import os
|
|
import sys
|
|
|
|
|
|
def byteToStr(v):
|
|
return chr((v & 0xF) + 97) + chr(((v >> 4) & 0xF) + 97)
|
|
|
|
def wordToStr(v):
|
|
return byteToStr(v & 0xFF) + byteToStr((v >> 8) & 0xFF)
|
|
|
|
# Reimplementation of u_data from scriptD.js
|
|
def _u_data(pixel_indices, c, px_ind_start):
|
|
rqMsg = ''
|
|
pxInd = px_ind_start
|
|
max_rq_len = 1000 # Max length of rqMsg
|
|
|
|
if c == -1: # 16-bit values
|
|
while pxInd < len(pixel_indices) and len(rqMsg) < max_rq_len:
|
|
v = 0
|
|
for i in range(0, 16, 2): # This means 8 iterations, packing 8 pixels
|
|
if pxInd < len(pixel_indices):
|
|
v |= (pixel_indices[pxInd] << i) # This is likely wrong, should be 4 bits per pixel
|
|
pxInd += 1
|
|
rqMsg += wordToStr(v)
|
|
elif c == -2: # 7-color, 4-bit values
|
|
while pxInd < len(pixel_indices) and len(rqMsg) < max_rq_len:
|
|
v = 0
|
|
for i in range(0, 16, 4): # 4 iterations, packing 4 pixels
|
|
if pxInd < len(pixel_indices):
|
|
v |= (pixel_indices[pxInd] << i)
|
|
pxInd += 1
|
|
rqMsg += wordToStr(v)
|
|
else: # Monochrome, 1-bit values
|
|
while pxInd < len(pixel_indices) and len(rqMsg) < max_rq_len:
|
|
v = 0
|
|
for i in range(8): # Packs 8 pixels into 1 byte
|
|
if pxInd < len(pixel_indices) and pixel_indices[pxInd] != c:
|
|
v |= (128 >> i)
|
|
pxInd += 1
|
|
rqMsg += byteToStr(v)
|
|
return rqMsg, pxInd
|
|
|
|
# Reimplementation of u_line from scriptD.js
|
|
def _u_line(pixel_indices, c, px_ind_start):
|
|
rqMsg = ''
|
|
pxInd = px_ind_start
|
|
max_rq_len = 1000 # Max length of rqMsg
|
|
|
|
while len(rqMsg) < max_rq_len:
|
|
x = 0
|
|
while x < 122: # Processes 122 pixels at a time
|
|
v = 0
|
|
for i in range(8):
|
|
if pxInd < len(pixel_indices) and x < 122:
|
|
if pixel_indices[pxInd] != c:
|
|
v |= (128 >> i)
|
|
pxInd += 1
|
|
x += 1
|
|
else:
|
|
break # Break if no more pixels or 122 pixels processed
|
|
rqMsg += byteToStr(v)
|
|
if x >= 122: # If 122 pixels processed, break inner loop
|
|
break
|
|
return rqMsg, pxInd
|
|
|
|
def upload_image(img, ip_addr, epd_ind, epdArr, palArr, getNear):
|
|
print(f"[DEBUG] Starting upload_image for EPD index {epd_ind} to {ip_addr}")
|
|
url_prefix = f"http://{ip_addr}/"
|
|
w, h = img.size
|
|
|
|
pal_ind = epdArr[epd_ind][2]
|
|
curPal = palArr[pal_ind]
|
|
pixels = list(img.getdata())
|
|
pixel_indices = [getNear(r,g,b, curPal) for r,g,b in pixels]
|
|
|
|
pxInd = 0
|
|
stInd = 0
|
|
|
|
def u_send(cmd, next_state=False):
|
|
nonlocal stInd
|
|
full_url = url_prefix + cmd
|
|
try:
|
|
response = requests.post(full_url)
|
|
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
|
|
if next_state:
|
|
stInd += 1
|
|
return 0
|
|
except requests.exceptions.RequestException as e:
|
|
print(f"[ERROR] Error sending command {cmd}: {e}")
|
|
raise # Re-raise the exception to stop execution
|
|
|
|
def u_next():
|
|
nonlocal pxInd
|
|
pxInd = 0
|
|
return u_send('NEXT_', True)
|
|
|
|
def u_done():
|
|
sys.stdout.write('\n') # Ensure progress bar finishes on a new line
|
|
print("Image upload complete!")
|
|
return u_send('SHOW_', True)
|
|
|
|
def u_show(a_len, k1, k2, rqMsg_val):
|
|
nonlocal pxInd
|
|
total_pixels = len(pixel_indices)
|
|
current_progress_pixels = pxInd
|
|
|
|
overall_percentage = (current_progress_pixels / total_pixels) * 100 if total_pixels > 0 else 0
|
|
|
|
bar_length = 50
|
|
filled_length = int(bar_length * overall_percentage // 100)
|
|
bar = '#' * filled_length + '-' * (bar_length - filled_length)
|
|
sys.stdout.write(f'\rProgress: |{bar}| {overall_percentage:.2f}%')
|
|
sys.stdout.flush()
|
|
|
|
return u_send(rqMsg_val + wordToStr(len(rqMsg_val)) + 'LOAD_', pxInd >= a_len)
|
|
|
|
# Main upload logic based on scriptD.js
|
|
try:
|
|
# Initial EPD command
|
|
epd_cmd_char = chr(epd_ind + 97) if epd_ind < 26 else chr(epd_ind - 26 + 65)
|
|
u_send(f'EPD{epd_cmd_char}_')
|
|
|
|
# Conditional logic based on epd_ind, mimicking scriptD.js
|
|
if epd_ind in [3, 39, 43]:
|
|
# u_line flow
|
|
while True:
|
|
if stInd == 0:
|
|
rqMsg, pxInd = _u_line(pixel_indices, 0, pxInd)
|
|
u_show(len(pixel_indices), 0, 100, rqMsg)
|
|
elif stInd == 1:
|
|
u_done()
|
|
break
|
|
elif epd_ind == 40:
|
|
# u_line with u_next flow
|
|
while True:
|
|
if stInd == 0:
|
|
rqMsg, pxInd = _u_line(pixel_indices, 0, pxInd)
|
|
u_show(len(pixel_indices), 0, 50, rqMsg)
|
|
elif stInd == 1:
|
|
u_next()
|
|
elif stInd == 2:
|
|
rqMsg, pxInd = _u_line(pixel_indices, 3, pxInd)
|
|
u_show(len(pixel_indices), 50, 50, rqMsg)
|
|
elif stInd == 3:
|
|
u_done()
|
|
break
|
|
elif epd_ind in [0, 3, 6, 7, 9, 12, 16, 19, 22, 26, 27, 28]:
|
|
# u_data flow (monochrome)
|
|
while True:
|
|
if stInd == 0:
|
|
rqMsg, pxInd = _u_data(pixel_indices, 0, pxInd)
|
|
u_show(len(pixel_indices), 0, 100, rqMsg)
|
|
elif stInd == 1:
|
|
u_done()
|
|
break
|
|
elif 15 < epd_ind < 22:
|
|
# u_data flow (16-bit values, c=-1)
|
|
while True:
|
|
if stInd == 0:
|
|
rqMsg, pxInd = _u_data(pixel_indices, -1, pxInd)
|
|
u_show(len(pixel_indices), 0, 100, rqMsg)
|
|
elif stInd == 1:
|
|
u_done()
|
|
break
|
|
elif epd_ind in [25, 37]:
|
|
# u_data flow (7-color, c=-2)
|
|
while True:
|
|
if stInd == 0:
|
|
rqMsg, pxInd = _u_data(pixel_indices, -2, pxInd)
|
|
u_show(len(pixel_indices), 0, 100, rqMsg)
|
|
elif stInd == 1:
|
|
u_done()
|
|
break
|
|
else:
|
|
# Default u_data flow with u_next
|
|
while True:
|
|
if stInd == 0:
|
|
c_val = -1 if epd_ind in [1, 12] else 0
|
|
rqMsg, pxInd = _u_data(pixel_indices, c_val, pxInd)
|
|
u_show(len(pixel_indices), 0, 50, rqMsg)
|
|
elif stInd == 1:
|
|
u_next()
|
|
elif stInd == 2:
|
|
# Special handling for 7.5b V2 (epd_ind 23) red channel
|
|
if epd_ind == 23:
|
|
# Encode only red pixels (palette index 2)
|
|
red_pixel_indices = [0 if p == 2 else 2 for p in pixel_indices] # Invert red channel: 0 for red, 2 for non-red
|
|
rqMsg, pxInd = _u_data(red_pixel_indices, 0, pxInd) # Use monochrome encoding for this layer
|
|
else:
|
|
rqMsg, pxInd = _u_data(pixel_indices, 3, pxInd)
|
|
u_show(len(pixel_indices), 50, 50, rqMsg)
|
|
elif stInd == 3:
|
|
u_done()
|
|
break
|
|
|
|
print("Image uploaded successfully!")
|
|
except requests.exceptions.RequestException as e:
|
|
print(f"[ERROR] Error during image upload: {e}")
|
|
except Exception as e:
|
|
print(f"[ERROR] An unexpected error occurred during upload: {e}")
|