214 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			7.7 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}")
 |