Scrolling works!!1!
This commit is contained in:
parent
a4d24551d5
commit
c2d5c19dcc
8 changed files with 137 additions and 80 deletions
|
|
@ -42,7 +42,7 @@
|
|||
<Option Name="IPUserFilesDir" Val="$PIPUSERFILESDIR"/>
|
||||
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="611"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="616"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ input in_blank, in_vsync, in_hsync,
|
|||
input [19:0] glyphmem_data,
|
||||
output [15:0] glyphmem_r_addr,
|
||||
|
||||
input [11:0] scroll_y,
|
||||
|
||||
output out_hsync, out_vsync,
|
||||
output [7:0] out_red,
|
||||
output [7:0] out_green,
|
||||
|
|
@ -158,11 +160,11 @@ always @(posedge clk) begin
|
|||
end
|
||||
|
||||
if (in_vsync_last && !in_vsync) begin
|
||||
glyph_y <= 0;
|
||||
px_y <= 0;
|
||||
glyph_y <= scroll_y / FONT_GLYPH_H;
|
||||
px_y <= scroll_y % FONT_GLYPH_H;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ wire [19:0] glyph_buffer_w_data;
|
|||
wire win_blank;
|
||||
wire [11:0] win_w;
|
||||
wire [11:0] win_h;
|
||||
wire [11:0] win_scroll_y;
|
||||
wire out_data_en;
|
||||
wire out_data_valid;
|
||||
wire [7:0] matcher_debug;
|
||||
|
|
@ -306,6 +307,8 @@ term_renderer #(
|
|||
.in_blank(win_blank),
|
||||
.in_vsync(in_vsync),
|
||||
.in_hsync(in_hsync),
|
||||
|
||||
.scroll_y(win_scroll_y),
|
||||
|
||||
.out_hsync(),
|
||||
.out_vsync(),
|
||||
|
|
@ -347,6 +350,7 @@ window_matcher window_matcher_i (
|
|||
.win_locked(win_locked),
|
||||
.win_w(win_w),
|
||||
.win_h(win_h),
|
||||
.win_scroll_y(win_scroll_y),
|
||||
|
||||
.win_x_dbg(win_x_dbg),
|
||||
.win_y_dbg(win_y_dbg),
|
||||
|
|
@ -368,4 +372,4 @@ window_matcher window_matcher_i (
|
|||
.out_blue(out_blue)
|
||||
);
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ module window_matcher(
|
|||
output reg [11:0] win_h,
|
||||
output reg [11:0] win_right,
|
||||
output reg [11:0] win_bottom,
|
||||
output reg [11:0] win_scroll_y,
|
||||
output reg win_locked,
|
||||
input [7:0] win_red, [7:0] win_green, [7:0] win_blue,
|
||||
|
||||
|
|
@ -208,6 +209,8 @@ module window_matcher(
|
|||
reg [11:0] win_y_int;
|
||||
reg [11:0] win_w_int;
|
||||
reg [11:0] win_h_int;
|
||||
reg [11:0] win_scroll_y_int;
|
||||
reg [11:0] win_sof_marker_int;
|
||||
|
||||
assign win_x_dbg = win_x_int;
|
||||
assign win_y_dbg = win_y_int;
|
||||
|
|
@ -221,17 +224,11 @@ module window_matcher(
|
|||
ST_MAT_RX3 = 5'b01000,
|
||||
ST_MAT_DATA = 5'b10000;
|
||||
reg [4:0] matcher_state;
|
||||
wire matched = matcher_state[4];
|
||||
reg matched;
|
||||
|
||||
reg [11:0] dval_x_reg;
|
||||
reg [11:0] dval_y_reg;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst == 1) begin
|
||||
out_data_valid <= 0;
|
||||
out_data_en <= 0;
|
||||
end
|
||||
|
||||
if (rst || in_vsync) begin
|
||||
matcher_state <= ST_MAT_WAITING;
|
||||
win_x_int <= 0;
|
||||
|
|
@ -239,68 +236,82 @@ module window_matcher(
|
|||
win_w_int <= 0;
|
||||
win_h_int <= 0;
|
||||
dval_x_reg <= 0;
|
||||
dval_y_reg <= 0;
|
||||
win_scroll_y_int <= 0;
|
||||
win_sof_marker_int <= 0;
|
||||
matched <= 0;
|
||||
out_data_en <= 0;
|
||||
out_data_valid <= 0;
|
||||
end
|
||||
|
||||
if (!rst) begin
|
||||
if (in_blank) begin
|
||||
/* Reset state if the header is only partially contained in this frame */
|
||||
if (matcher_state != ST_MAT_DATA) begin
|
||||
matcher_state <= ST_MAT_WAITING;
|
||||
end
|
||||
if (!in_blank_reg) begin
|
||||
if (matcher_state != ST_MAT_DATA) begin
|
||||
out_data_en <= 0;
|
||||
end
|
||||
|
||||
matcher_state <= ST_MAT_WAITING;
|
||||
end
|
||||
|
||||
end else begin
|
||||
case (matcher_state)
|
||||
ST_MAT_WAITING: begin
|
||||
if (in_pxd_pattern_match) begin
|
||||
matcher_state <= ST_MAT_RX0;
|
||||
win_x_int <= scan_x_reg[7];
|
||||
win_y_int <= scan_y;
|
||||
if (!matched) begin
|
||||
win_x_int <= scan_x_reg[7];
|
||||
win_y_int <= scan_y;
|
||||
end
|
||||
end
|
||||
end
|
||||
ST_MAT_RX0: begin
|
||||
matcher_state <= ST_MAT_RX1;
|
||||
win_sof_marker_int <= in_pxd;
|
||||
end
|
||||
|
||||
ST_MAT_RX1: begin
|
||||
matcher_state <= ST_MAT_RX2;
|
||||
if (!matched) begin
|
||||
win_scroll_y_int <= in_pxd;
|
||||
end
|
||||
end
|
||||
|
||||
ST_MAT_RX2: begin
|
||||
matcher_state <= ST_MAT_RX3;
|
||||
win_w_int <= in_pxd;
|
||||
if (!matched) begin
|
||||
win_w_int <= in_pxd;
|
||||
end
|
||||
end
|
||||
|
||||
ST_MAT_RX3: begin
|
||||
matcher_state <= ST_MAT_DATA;
|
||||
win_h_int <= in_pxd;
|
||||
out_data_valid <= 1;
|
||||
out_data_en <= 1;
|
||||
dval_x_reg <= 13;
|
||||
dval_y_reg <= 0;
|
||||
if (!matched) begin
|
||||
matched <= 1;
|
||||
win_h_int <= in_pxd;
|
||||
end
|
||||
|
||||
if (win_sof_marker_int[7]) begin
|
||||
out_data_valid <= 1;
|
||||
out_data_en <= 1;
|
||||
|
||||
end else if (out_data_en) begin
|
||||
out_data_valid <= 1;
|
||||
end
|
||||
|
||||
dval_x_reg <= 13;
|
||||
end
|
||||
|
||||
ST_MAT_DATA: begin
|
||||
if (out_data_en) begin
|
||||
dval_x_reg <= dval_x_reg + 1;
|
||||
end
|
||||
|
||||
if (dval_x_reg == win_w_int || in_blank) begin
|
||||
out_data_valid <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
if (matcher_state == ST_MAT_DATA) begin
|
||||
/* blank */
|
||||
if (scan_x == win_x_int && out_data_en) begin
|
||||
out_data_valid <= 1;
|
||||
dval_x_reg <= 1;
|
||||
|
||||
end else if (out_data_en) begin
|
||||
dval_x_reg <= dval_x_reg + 1;
|
||||
end
|
||||
|
||||
if (dval_x_reg == win_w_int || in_blank) begin
|
||||
out_data_valid <= 0;
|
||||
end
|
||||
|
||||
if (!in_blank_reg && in_blank) begin
|
||||
dval_y_reg <= dval_y_reg + 1;
|
||||
end
|
||||
|
||||
if (dval_y_reg == win_h_int) begin
|
||||
out_data_en <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -351,6 +362,7 @@ module window_matcher(
|
|||
win_y <= 0;
|
||||
win_right <= 0;
|
||||
win_bottom <= 0;
|
||||
win_scroll_y <= 0;
|
||||
|
||||
end else begin
|
||||
if (in_vsync_reg == 0 && in_vsync == 1) begin
|
||||
|
|
@ -363,6 +375,7 @@ module window_matcher(
|
|||
win_y <= win_y_int;
|
||||
win_right <= win_x_int + win_w_int + 1;
|
||||
win_bottom <= win_y_int + win_h_int + 1;
|
||||
win_scroll_y <= win_scroll_y_int;
|
||||
|
||||
end else begin
|
||||
win_w <= 0;
|
||||
|
|
@ -371,6 +384,7 @@ module window_matcher(
|
|||
win_y <= 0;
|
||||
win_right <= 0;
|
||||
win_bottom <= 0;
|
||||
win_scroll_y <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 55,
|
||||
"execution_count": 61,
|
||||
"id": "preliminary-virus",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
|
|
@ -104,12 +104,13 @@
|
|||
" def encode_val(val):\n",
|
||||
" return np.array([(val//65536)&0xff, (val%65536//256)&0xff, (val%256)&0xff]).astype(int)\n",
|
||||
" \n",
|
||||
" win_data[0, :8, :3] = WINDOW_MAGIC\n",
|
||||
" win_data[0, 8, :3] = encode_val(win_x)\n",
|
||||
" win_data[0, 9, :3] = encode_val(win_y)\n",
|
||||
" win_data[0, 10, :3] = encode_val(win_w)\n",
|
||||
" win_data[0, 11, :3] = encode_val(win_h)\n",
|
||||
" win_data[0, :12, 3] |= AlphaFlags.WIN_HEADER.value;\n",
|
||||
" for y in range(win_h):\n",
|
||||
" win_data[y, :8, :3] = WINDOW_MAGIC\n",
|
||||
" win_data[y, 8, :3] = encode_val(0x85 if y%3 == 0 else 0)\n",
|
||||
" win_data[y, 9, :3] = encode_val(y)\n",
|
||||
" win_data[y, 10, :3] = encode_val(win_w)\n",
|
||||
" win_data[y, 11, :3] = encode_val(win_h)\n",
|
||||
" win_data[y, :12, 3] |= AlphaFlags.WIN_HEADER.value;\n",
|
||||
" \n",
|
||||
" win_h, win_w, _ = win_data.shape\n",
|
||||
" h, w, _ = fb.shape\n",
|
||||
|
|
@ -721,7 +722,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 56,
|
||||
"execution_count": 62,
|
||||
"id": "7da9e05f-aa7e-42e6-b1ee-2c6453468bf3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
|
|
@ -731,13 +732,13 @@
|
|||
"(-0.5, 229.5, 109.5, -0.5)"
|
||||
]
|
||||
},
|
||||
"execution_count": 56,
|
||||
"execution_count": 62,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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\n",
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAqsAAAFOCAYAAAChelRdAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAI5ElEQVR4nO3d0aamVRjA8fkSMYohIqIREZHdHXQpcwmdR0SJiIiIaESU7iVzCXMJ3cHb2bZi77HWevvs/8Hvd/T6vsV8J8Pfsx/vuhzH8QgAAIpee+gfAAAA9xGrAABkiVUAALLEKgAAWWIVAIAssQoAQNbrr/rycrl4rxUAAFd3HMflrs9NVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAICs1x/6B8BVPHl6+3hzc/PK5/989vlnt8/PHj25fX7x4sXt88t/vhn+oS+G54+G58e3T28++vv2+TKcuLzis4d6rv77fz59/gjOunn57KF/ArDBZBUAgCyxCgBAljUAWDb+6f9y76m1MwDAXUxWAQDIEqsAAGRZA4BTrAEAwDWZrAIAkCVWAQDIsgYAy8ZLAb6cOG8NAAB2mawCAJBlsgrLxveszvwXMlkFgF0mqwAAZIlVAACyrAHAKd6zCgDXZLIKAECWWAUAIMsaACwb37P61cR5awAAsMtkFQCALLEKAECWNQBYNl4K8MbEeWsAALDLZBUAgCyxCgBAljUAOMWlAABwTSarAABkiVUAALKsAcCy8VKAryfOWwMAgF0mqwAAZIlVAACyrAHAsvFSgMcT560BAMAuk1UAALLEKgAAWdYA4BSXAgDANZmsAgCQJVYBAMiyBgDLxksBvp04bw0AAHaZrAIAkCVWAQDIsgYAy8ZLAd6aOG8NAAB2mawCAJAlVgEAyLIGAKe4FAAArslkFQCALLEKAECWNQBYNl4K8N3EeWsAALDLZBUAgCyTVVg2vmf1ycR5k1UA2GWyCgBAllgFACDLGgCc4j2rAHBNJqsAAGSJVQAAsqwBwLLxPavfT5y3BgAAu0xWAQDIEqsAAGRZA4Bl46UAb0+ctwYAALtMVgEAyBKrAABkWQOAU1wKAADXZLIKAECWWAUAIMsaACwbLwX4YeK8NQAA2GWyCgBAllgFACDLGgAsGy8FeGfivDUAANhlsgoAQJZYBQAgyxoAnOJSAAC4JpNVAACyxCoAAFnWAGDZeCnAjxPnrQEAwC6TVQAAssQqAABZ1gBg2XgpwLsT560BAMAuk1UAALLEKgAAWdYA4BSXAgDANZmsAgCQJVYBAMiyBgDLxksBfpo4bw0AAHaZrAIAkGWyCsvG96y+N3HeZBUAdpmsAgCQJVYBAMiyBgCneM8qAFyTySoAAFliFQCALGsAsGx8z+rPE+etAQDALpNVAACyxCoAAFnWAGDZeCnA+xPnrQEAwC6TVQAAssQqAABZ1gDgFJcCAMA1mawCAJAlVgEAyLIGAMvGSwF+mThvDQAAdpmsAgCQJVYBAMiyBgDLxksBPpg4bw0AAHaZrAIAkCVWAQDIsgYAp7gUAACuyWQVAIAssQoAQJY1AFg2Xgrw68R5awAAsMtkFQCALLEKAECWNQBYNl4K8OHEeWsAALDLZBUAgCyxCgBAljUAOMWlAABwTSarAABkiVUAALKsAcCy8VKA3ybOWwMAgF0mqwAAZIlVAACyrAHAsvFSgI8mzlsDAIBdJqsAAGSZrMIp49T0mDgDAKwwWQUAIEusAgCQZQ0Alo3vWf19eLYGAAD/N5NVAACyxCoAAFnWAGDZ+J7VjyfOWwMAgF0mqwAAZIlVAACyrAHAKTN/4rcGAAC7TFYBAMgSqwAAZFkDgGXjpQB/TJy3BgAAu0xWAQDIEqsAAGRZA4Bl46UAn0yctwYAALtMVgEAyBKrAABkWQOAU1wKAADXZLIKAECWWAUAIMsaACwbLwX4a+K8NQAA2GWyCgBAllgFACDLGgAsGy8F+HTivDUAANhlsgoAQJZYBQAg63Icx/1fXi73fwlhL54+f+ifAMTcvHz20D8BeIXjOO7cmzNZBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAg63Icx/1fXi73fwkAAP+T4zgud31usgoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWWIVAIAssQoAQJZYBQAgS6wCAJAlVgEAyBKrAABkXY7jeOjfAAAAdzJZBQAgS6wCAJAlVgEAyBKrAABkiVUAALLEKgAAWf8Cf2pIngd/lpUAAAAASUVORK5CYII=\n",
|
||||
"text/plain": [
|
||||
"<Figure size 864x864 with 1 Axes>"
|
||||
]
|
||||
|
|
@ -757,7 +758,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 57,
|
||||
"execution_count": 63,
|
||||
"id": "4d3a1a2d-4b31-47cf-8502-b45ac31a74e0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
|
|
@ -771,7 +772,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 58,
|
||||
"execution_count": 64,
|
||||
"id": "f542f9bc-671b-4b4e-a8f6-ece54783d619",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ int main(void)
|
|||
con_printf("Received %d bytes: %s\r\n", rv, rd_buf);
|
||||
*/
|
||||
|
||||
con_printf_blocking(" #%u", i);
|
||||
con_printf_blocking(" #%u heap memory usage: %zu used / %zu free / %zu fresh blocks", i, ta_num_used(), ta_num_free(), ta_num_fresh());
|
||||
/*
|
||||
if (k == 0)
|
||||
spif_printf(&spif, "\33[1m");
|
||||
|
|
@ -379,6 +379,13 @@ int main(void)
|
|||
spif_printf(&spif, "\033[1;91mDecryption error!\033[0m\nInvalid payload size %zx\n", payload_len);
|
||||
continue;
|
||||
}
|
||||
con_printf_blocking("Payload size %zu\r\n", payload_len);
|
||||
for (size_t i=0; i<payload_len; i++) {
|
||||
con_printf_blocking("%02x ", payload_buf[i+4]);
|
||||
if (i%16 == 15)
|
||||
con_printf_blocking("\r\n");
|
||||
}
|
||||
con_printf_blocking("\r\n");
|
||||
|
||||
unsigned char file_key[16];
|
||||
err = parse_age_buf(&ks, payload_buf + sizeof(uint32_t), payload_len+1, file_key);
|
||||
|
|
|
|||
|
|
@ -39,10 +39,15 @@ FONT_FG_COLOR = '#e0e010'
|
|||
def pack_html(payload_img_cid, hint_img_data):
|
||||
return textwrap.dedent(f'''\
|
||||
<html style="margin: 0; padding: 0; border: 0; width: 100%; height: 100%">
|
||||
<body style="border-style: solid; border-width: 2px; border-color: {BORDER_COLOR}; margin: 0; padding: 0; \
|
||||
background-color: {BACKGROUND_COLOR}; background-image: url({data_url(hint_img_data)}); \
|
||||
width: calc(100% - 4px); height: calc(100% - 4px); overflow: hidden">
|
||||
<img src="cid:{payload_img_cid}" style="margin: 0; padding: 0"/>
|
||||
<body style="margin: 0; padding: 0; border: 0; width: 100%; \
|
||||
background-color: {BACKGROUND_COLOR}; background-image: url({data_url(hint_img_data)})">
|
||||
<div style="margin: 0; padding: 2px; width: calc(100% - 4px)">
|
||||
<img src="cid:{payload_img_cid}" style="margin: 0; padding: 0"/>
|
||||
</div>
|
||||
<div style="border-left: 2px; border-top: 2px; border-bottom: 2px; border-right: 20px; \
|
||||
border-style: solid; border-color: {BORDER_COLOR}; margin: 0; padding: 0; \
|
||||
width: calc(100% - 2px - 20px); height: calc(100% - 4px); position: fixed; top: 0; left: 0">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
''').strip()
|
||||
|
|
@ -84,8 +89,11 @@ def img_to_bytes(img, fmt='png'):
|
|||
@click.option('--smtp-port', type=int, default=465)
|
||||
@click.option('-k', '--key', 'keys', multiple=True, required=True)
|
||||
@click.option('-s', '--subject', default='tachibana/age encrypted message')
|
||||
@click.option('--payload-width', type=int, default=300)
|
||||
@click.option('--payload-height', type=int)
|
||||
@click.argument('content', type=click.File('r'))
|
||||
def create_age_email(content, sender, recipients, cc, bcc, keys, subject, smtp_server, smtp_port, smtp_user, smtp_password):
|
||||
def create_age_email(content, sender, recipients, cc, bcc, keys, subject, smtp_server, smtp_port, smtp_user,
|
||||
smtp_password, payload_width, payload_height):
|
||||
|
||||
encrypted = age_encrypt(content.read(), keys)
|
||||
|
||||
|
|
@ -106,9 +114,11 @@ def create_age_email(content, sender, recipients, cc, bcc, keys, subject, smtp_s
|
|||
# remove <...> angle brackets from cids in <img> tags
|
||||
msg.set_content(pack_html(payload_img_cid[1:-1], hint_img_data), subtype='html')
|
||||
|
||||
w = max(200, math.ceil(math.sqrt(len(encrypted))))
|
||||
h = math.ceil((len(encrypted) + 64) / w)
|
||||
img_bytes = img_to_bytes(tb_data_encoder.data_encode(encrypted, w, h))
|
||||
if payload_height is None:
|
||||
payload_height = len(encrypted) // 16 * 16
|
||||
img_bytes = img_to_bytes(tb_data_encoder.data_encode(encrypted, payload_width, payload_height))
|
||||
#with open('/tmp/test.png', 'wb') as f:
|
||||
# f.write(img_bytes)
|
||||
msg.add_related(img_bytes, 'image', 'png', cid=payload_img_cid)
|
||||
|
||||
if not smtp_server:
|
||||
|
|
@ -122,7 +132,7 @@ def create_age_email(content, sender, recipients, cc, bcc, keys, subject, smtp_s
|
|||
smtp.login(smtp_user, smtp_password)
|
||||
smtp.send_message(msg)
|
||||
smtp.quit()
|
||||
print('Message sent!')
|
||||
print('Message sent!', file=sys.stderr)
|
||||
|
||||
if __name__ == '__main__':
|
||||
#print(pack_html('foobar'))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import math
|
||||
|
||||
import numpy as np
|
||||
import click
|
||||
|
|
@ -22,26 +23,44 @@ def tb_int_to_px(val):
|
|||
return np.array([(val//0x10000)&0xff, (val//0x100)&0xff, val&0xff], dtype=np.uint8)
|
||||
|
||||
def data_encode(data, width, height):
|
||||
HEADER_W = 12
|
||||
assert width > HEADER_W
|
||||
data = struct.pack('>I', len(data)) + data
|
||||
data = np.frombuffer(data, dtype=np.uint8)
|
||||
for i in range(len(data) - 4):
|
||||
print(f'{data[i+4]:02x} ', end='')
|
||||
if i%16 == 15 and i > 0:
|
||||
print()
|
||||
|
||||
data_expanded = np.repeat(data, 2).reshape((-1, 2))
|
||||
data_expanded[:, 0] &= 0xf0
|
||||
data_expanded[:, 1] = (data_expanded[:, 1] & 0x0f) << 4
|
||||
data_expanded = data_expanded.flatten()
|
||||
|
||||
win = np.zeros([height*width*3], dtype=np.uint8)
|
||||
win[12*3:12*3+len(data_expanded)] = data_expanded
|
||||
win = win.reshape((height, width, 3))
|
||||
payload_w = width-HEADER_W
|
||||
line_capacity = payload_w*3
|
||||
print(payload_w, line_capacity, line_capacity / 2)
|
||||
block_height = math.ceil(len(data_expanded)/line_capacity)
|
||||
data_expanded = np.hstack([data_expanded, np.zeros(line_capacity*block_height - len(data_expanded), dtype=np.uint8)])
|
||||
block = np.zeros((block_height, payload_w, 3), dtype=np.uint8)
|
||||
block[:,:,:] = data_expanded.reshape((block_height, payload_w, 3))
|
||||
|
||||
win[0, :8] = WINDOW_MAGIC
|
||||
win[0, 8] = tb_int_to_px(0)
|
||||
win[0, 9] = tb_int_to_px(0)
|
||||
win[0, 10] = tb_int_to_px(width)
|
||||
win[0, 11] = tb_int_to_px(height)
|
||||
payload_area = np.vstack(
|
||||
[block] * (height // block_height) +
|
||||
[np.zeros((height % block_height, payload_w, 3), dtype=np.uint8)])
|
||||
|
||||
header = np.zeros((height, HEADER_W, 3), dtype=np.uint8)
|
||||
for y in range(height):
|
||||
header[y, :8] = WINDOW_MAGIC
|
||||
if y % block_height == 0 and y + block_height <= height:
|
||||
header[y, 8] = tb_int_to_px(0x88)
|
||||
else:
|
||||
header[y, 8] = tb_int_to_px(0)
|
||||
header[y, 9] = tb_int_to_px(y)
|
||||
header[y, 10] = tb_int_to_px(width)
|
||||
header[y, 11] = tb_int_to_px(height)
|
||||
|
||||
#print('out:', ' '.join(f'{x:02x}' for x in win.flatten()[:256]))
|
||||
return Image.fromarray(win)
|
||||
return Image.fromarray(np.hstack([header, payload_area]))
|
||||
|
||||
@click.command()
|
||||
@click.option('-w', '--width', type=int, default=400)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue