2262 dispWin.x2 = dispWinTemp.x2; |
2262 dispWin.x2 = dispWinTemp.x2; |
2263 dispWin.y2 = dispWinTemp.y2; |
2263 dispWin.y2 = dispWinTemp.y2; |
2264 } |
2264 } |
2265 |
2265 |
2266 |
2266 |
2267 // ================ JPG SUPPORT ================================================ |
|
2268 // User defined device identifier |
|
2269 typedef struct { |
|
2270 FILE *fhndl; // File handler for input function |
|
2271 int x; // image top left point X position |
|
2272 int y; // image top left point Y position |
|
2273 uint8_t *membuff; // memory buffer containing the image |
|
2274 uint32_t bufsize; // size of the memory buffer |
|
2275 uint32_t bufptr; // memory buffer current position |
|
2276 color_t *linbuf[2]; // memory buffer used for display output |
|
2277 uint8_t linbuf_idx; |
|
2278 } JPGIODEV; |
|
2279 |
|
2280 |
|
2281 // User defined call-back function to input JPEG data from file |
|
2282 //--------------------- |
|
2283 static UINT tjd_input ( |
|
2284 JDEC* jd, // Decompression object |
|
2285 BYTE* buff, // Pointer to the read buffer (NULL:skip) |
|
2286 UINT nd // Number of bytes to read/skip from input stream |
|
2287 ) |
|
2288 { |
|
2289 int rb = 0; |
|
2290 // Device identifier for the session (5th argument of jd_prepare function) |
|
2291 JPGIODEV *dev = (JPGIODEV*)jd->device; |
|
2292 |
|
2293 if (buff) { // Read nd bytes from the input strem |
|
2294 rb = fread(buff, 1, nd, dev->fhndl); |
|
2295 return rb; // Returns actual number of bytes read |
|
2296 } |
|
2297 else { // Remove nd bytes from the input stream |
|
2298 if (fseek(dev->fhndl, nd, SEEK_CUR) >= 0) return nd; |
|
2299 else return 0; |
|
2300 } |
|
2301 } |
|
2302 |
|
2303 // User defined call-back function to input JPEG data from memory buffer |
|
2304 //------------------------- |
|
2305 static UINT tjd_buf_input ( |
|
2306 JDEC* jd, // Decompression object |
|
2307 BYTE* buff, // Pointer to the read buffer (NULL:skip) |
|
2308 UINT nd // Number of bytes to read/skip from input stream |
|
2309 ) |
|
2310 { |
|
2311 // Device identifier for the session (5th argument of jd_prepare function) |
|
2312 JPGIODEV *dev = (JPGIODEV*)jd->device; |
|
2313 if (!dev->membuff) return 0; |
|
2314 if (dev->bufptr >= (dev->bufsize + 2)) return 0; // end of stream |
|
2315 |
|
2316 if ((dev->bufptr + nd) > (dev->bufsize + 2)) nd = (dev->bufsize + 2) - dev->bufptr; |
|
2317 |
|
2318 if (buff) { // Read nd bytes from the input strem |
|
2319 memcpy(buff, dev->membuff + dev->bufptr, nd); |
|
2320 dev->bufptr += nd; |
|
2321 return nd; // Returns number of bytes read |
|
2322 } |
|
2323 else { // Remove nd bytes from the input stream |
|
2324 dev->bufptr += nd; |
|
2325 return nd; |
|
2326 } |
|
2327 } |
|
2328 |
|
2329 // User defined call-back function to output RGB bitmap to display device |
|
2330 //---------------------- |
|
2331 static UINT tjd_output ( |
|
2332 JDEC* jd, // Decompression object of current session |
|
2333 void* bitmap, // Bitmap data to be output |
|
2334 JRECT* rect // Rectangular region to output |
|
2335 ) |
|
2336 { |
|
2337 // Device identifier for the session (5th argument of jd_prepare function) |
|
2338 JPGIODEV *dev = (JPGIODEV*)jd->device; |
|
2339 |
|
2340 // ** Put the rectangular into the display device ** |
|
2341 int x; |
|
2342 int y; |
|
2343 int dleft, dtop, dright, dbottom; |
|
2344 BYTE *src = (BYTE*)bitmap; |
|
2345 |
|
2346 int left = rect->left + dev->x; |
|
2347 int top = rect->top + dev->y; |
|
2348 int right = rect->right + dev->x; |
|
2349 int bottom = rect->bottom + dev->y; |
|
2350 |
|
2351 if ((left > dispWin.x2) || (top > dispWin.y2)) return 1; // out of screen area, return |
|
2352 if ((right < dispWin.x1) || (bottom < dispWin.y1)) return 1;// out of screen area, return |
|
2353 |
|
2354 if (left < dispWin.x1) dleft = dispWin.x1; |
|
2355 else dleft = left; |
|
2356 if (top < dispWin.y1) dtop = dispWin.y1; |
|
2357 else dtop = top; |
|
2358 if (right > dispWin.x2) dright = dispWin.x2; |
|
2359 else dright = right; |
|
2360 if (bottom > dispWin.y2) dbottom = dispWin.y2; |
|
2361 else dbottom = bottom; |
|
2362 |
|
2363 if ((dleft > dispWin.x2) || (dtop > dispWin.y2)) return 1; // out of screen area, return |
|
2364 if ((dright < dispWin.x1) || (dbottom < dispWin.y1)) return 1; // out of screen area, return |
|
2365 |
|
2366 uint32_t len = ((dright-dleft+1) * (dbottom-dtop+1)); // calculate length of data |
|
2367 |
|
2368 |
|
2369 if ((len > 0) && (len <= JPG_IMAGE_LINE_BUF_SIZE)) { |
|
2370 uint8_t *dest = (uint8_t *)(dev->linbuf[dev->linbuf_idx]); |
|
2371 |
|
2372 for (y = top; y <= bottom; y++) { |
|
2373 for (x = left; x <= right; x++) { |
|
2374 // Clip to display area |
|
2375 if ((x >= dleft) && (y >= dtop) && (x <= dright) && (y <= dbottom)) { |
|
2376 *dest++ = (*src++) & 0xFC; |
|
2377 *dest++ = (*src++) & 0xFC; |
|
2378 *dest++ = (*src++) & 0xFC; |
|
2379 } |
|
2380 else src += 3; // skip |
|
2381 } |
|
2382 } |
|
2383 wait_trans_finish(1); |
|
2384 send_data(dleft, dtop, dright, dbottom, len, dev->linbuf[dev->linbuf_idx]); |
|
2385 dev->linbuf_idx = ((dev->linbuf_idx + 1) & 1); |
|
2386 } |
|
2387 else { |
|
2388 wait_trans_finish(1); |
|
2389 printf("Data size error: %d jpg: (%d,%d,%d,%d) disp: (%d,%d,%d,%d)\r\n", len, left,top,right,bottom, dleft,dtop,dright,dbottom); |
|
2390 return 0; // stop decompression |
|
2391 } |
|
2392 |
|
2393 return 1; // Continue to decompression |
|
2394 } |
|
2395 |
|
2396 // tft.jpgimage(X, Y, scale, file_name, buf, size] |
|
2397 // X & Y can be < 0 ! |
|
2398 //================================================================================== |
|
2399 void TFT_jpg_image(int x, int y, uint8_t scale, char *fname, uint8_t *buf, int size) |
|
2400 { |
|
2401 JPGIODEV dev; |
|
2402 struct stat sb; |
|
2403 char *work = NULL; // Pointer to the working buffer (must be 4-byte aligned) |
|
2404 UINT sz_work = 3800; // Size of the working buffer (must be power of 2) |
|
2405 JDEC jd; // Decompression object (70 bytes) |
|
2406 JRESULT rc; |
|
2407 |
|
2408 dev.linbuf[0] = NULL; |
|
2409 dev.linbuf[1] = NULL; |
|
2410 dev.linbuf_idx = 0; |
|
2411 |
|
2412 dev.fhndl = NULL; |
|
2413 if (fname == NULL) { |
|
2414 // image from buffer |
|
2415 dev.membuff = buf; |
|
2416 dev.bufsize = size; |
|
2417 dev.bufptr = 0; |
|
2418 } |
|
2419 else { |
|
2420 // image from file |
|
2421 dev.membuff = NULL; |
|
2422 dev.bufsize = 0; |
|
2423 dev.bufptr = 0; |
|
2424 |
|
2425 if (stat(fname, &sb) != 0) { |
|
2426 if (image_debug) printf("File error: %ss\r\n", strerror(errno)); |
|
2427 goto exit; |
|
2428 } |
|
2429 |
|
2430 dev.fhndl = fopen(fname, "r"); |
|
2431 if (!dev.fhndl) { |
|
2432 if (image_debug) printf("Error opening file: %s\r\n", strerror(errno)); |
|
2433 goto exit; |
|
2434 } |
|
2435 } |
|
2436 |
|
2437 if (scale > 3) scale = 3; |
|
2438 |
|
2439 work = malloc(sz_work); |
|
2440 if (work) { |
|
2441 if (dev.membuff) rc = jd_prepare(&jd, tjd_buf_input, (void *)work, sz_work, &dev); |
|
2442 else rc = jd_prepare(&jd, tjd_input, (void *)work, sz_work, &dev); |
|
2443 if (rc == JDR_OK) { |
|
2444 if (x == CENTER) x = ((dispWin.x2 - dispWin.x1 + 1 - (int)(jd.width >> scale)) / 2) + dispWin.x1; |
|
2445 else if (x == RIGHT) x = dispWin.x2 + 1 - (int)(jd.width >> scale); |
|
2446 |
|
2447 if (y == CENTER) y = ((dispWin.y2 - dispWin.y1 + 1 - (int)(jd.height >> scale)) / 2) + dispWin.y1; |
|
2448 else if (y == BOTTOM) y = dispWin.y2 + 1 - (int)(jd.height >> scale); |
|
2449 |
|
2450 if (x < ((dispWin.x2-1) * -1)) x = (dispWin.x2-1) * -1; |
|
2451 if (y < ((dispWin.y2-1)) * -1) y = (dispWin.y2-1) * -1; |
|
2452 if (x > (dispWin.x2-1)) x = dispWin.x2 - 1; |
|
2453 if (y > (dispWin.y2-1)) y = dispWin.y2-1; |
|
2454 |
|
2455 dev.x = x; |
|
2456 dev.y = y; |
|
2457 |
|
2458 dev.linbuf[0] = heap_caps_malloc(JPG_IMAGE_LINE_BUF_SIZE*3, MALLOC_CAP_DMA); |
|
2459 if (dev.linbuf[0] == NULL) { |
|
2460 if (image_debug) printf("Error allocating line buffer #0\r\n"); |
|
2461 goto exit; |
|
2462 } |
|
2463 dev.linbuf[1] = heap_caps_malloc(JPG_IMAGE_LINE_BUF_SIZE*3, MALLOC_CAP_DMA); |
|
2464 if (dev.linbuf[1] == NULL) { |
|
2465 if (image_debug) printf("Error allocating line buffer #1\r\n"); |
|
2466 goto exit; |
|
2467 } |
|
2468 |
|
2469 // Start to decode the JPEG file |
|
2470 disp_select(); |
|
2471 rc = jd_decomp(&jd, tjd_output, scale); |
|
2472 disp_deselect(); |
|
2473 |
|
2474 if (rc != JDR_OK) { |
|
2475 if (image_debug) printf("jpg decompression error %d\r\n", rc); |
|
2476 } |
|
2477 if (image_debug) printf("Jpg size: %dx%d, position; %d,%d, scale: %d, bytes used: %d\r\n", jd.width, jd.height, x, y, scale, jd.sz_pool); |
|
2478 } |
|
2479 else { |
|
2480 if (image_debug) printf("jpg prepare error %d\r\n", rc); |
|
2481 } |
|
2482 } |
|
2483 else { |
|
2484 if (image_debug) printf("work buffer allocation error\r\n"); |
|
2485 } |
|
2486 |
|
2487 exit: |
|
2488 if (work) free(work); // free work buffer |
|
2489 if (dev.linbuf[0]) free(dev.linbuf[0]); |
|
2490 if (dev.linbuf[1]) free(dev.linbuf[1]); |
|
2491 if (dev.fhndl) fclose(dev.fhndl); // close input file |
|
2492 } |
|
2493 |
|
2494 |
|
2495 //==================================================================================== |
|
2496 int TFT_bmp_image(int x, int y, uint8_t scale, char *fname, uint8_t *imgbuf, int size) |
|
2497 { |
|
2498 FILE *fhndl = NULL; |
|
2499 struct stat sb; |
|
2500 int i, err=0; |
|
2501 int img_xsize, img_ysize, img_xstart, img_xlen, img_ystart, img_ylen; |
|
2502 int img_pos, img_pix_pos, scan_lines, rd_len; |
|
2503 uint8_t tmpc; |
|
2504 uint16_t wtemp; |
|
2505 uint32_t temp; |
|
2506 int disp_xstart, disp_xend, disp_ystart, disp_yend; |
|
2507 uint8_t buf[56]; |
|
2508 char err_buf[64]; |
|
2509 uint8_t *line_buf[2] = {NULL,NULL}; |
|
2510 uint8_t lb_idx = 0; |
|
2511 uint8_t *scale_buf = NULL; |
|
2512 uint8_t scale_pix; |
|
2513 uint16_t co[3] = {0,0,0}; // RGB sum |
|
2514 uint8_t npix; |
|
2515 |
|
2516 if (scale > 7) scale = 7; |
|
2517 scale_pix = scale+1; // scale factor ( 1~8 ) |
|
2518 |
|
2519 if (fname) { |
|
2520 // * File name is given, reading image from file |
|
2521 if (stat(fname, &sb) != 0) { |
|
2522 sprintf(err_buf, "opening file"); |
|
2523 err = -1; |
|
2524 goto exit; |
|
2525 } |
|
2526 size = sb.st_size; |
|
2527 fhndl = fopen(fname, "r"); |
|
2528 if (!fhndl) { |
|
2529 sprintf(err_buf, "opening file"); |
|
2530 err = -2; |
|
2531 goto exit; |
|
2532 } |
|
2533 |
|
2534 i = fread(buf, 1, 54, fhndl); // read header |
|
2535 } |
|
2536 else { |
|
2537 // * Reading image from buffer |
|
2538 if ((imgbuf) && (size > 54)) { |
|
2539 memcpy(buf, imgbuf, 54); |
|
2540 i = 54; |
|
2541 } |
|
2542 else i = 0; |
|
2543 } |
|
2544 |
|
2545 sprintf(err_buf, "reading header"); |
|
2546 if (i != 54) {err = -3; goto exit;} |
|
2547 |
|
2548 // ** Check image header and get image properties |
|
2549 if ((buf[0] != 'B') || (buf[1] != 'M')) {err=-4; goto exit;} // accept only images with 'BM' id |
|
2550 |
|
2551 memcpy(&temp, buf+2, 4); // file size |
|
2552 if (temp != size) {err=-5; goto exit;} |
|
2553 |
|
2554 memcpy(&img_pos, buf+10, 4); // start of pixel data |
|
2555 |
|
2556 memcpy(&temp, buf+14, 4); // BMP header size |
|
2557 if (temp != 40) {err=-6; goto exit;} |
|
2558 |
|
2559 memcpy(&wtemp, buf+26, 2); // the number of color planes |
|
2560 if (wtemp != 1) {err=-7; goto exit;} |
|
2561 |
|
2562 memcpy(&wtemp, buf+28, 2); // the number of bits per pixel |
|
2563 if (wtemp != 24) {err=-8; goto exit;} |
|
2564 |
|
2565 memcpy(&temp, buf+30, 4); // the compression method being used |
|
2566 if (temp != 0) {err=-9; goto exit;} |
|
2567 |
|
2568 memcpy(&img_xsize, buf+18, 4); // the bitmap width in pixels |
|
2569 memcpy(&img_ysize, buf+22, 4); // the bitmap height in pixels |
|
2570 |
|
2571 |
|
2572 // * scale image dimensions |
|
2573 |
|
2574 img_xlen = img_xsize / scale_pix; // image display horizontal size |
|
2575 img_ylen = img_ysize / scale_pix; // image display vertical size |
|
2576 |
|
2577 if (x == CENTER) x = ((dispWin.x2 - dispWin.x1 + 1 - img_xlen) / 2) + dispWin.x1; |
|
2578 else if (x == RIGHT) x = dispWin.x2 + 1 - img_xlen; |
|
2579 |
|
2580 if (y == CENTER) y = ((dispWin.y2 - dispWin.y1 + 1 - img_ylen) / 2) + dispWin.y1; |
|
2581 else if (y == BOTTOM) y = dispWin.y2 + 1 - img_ylen; |
|
2582 |
|
2583 if ((x < ((dispWin.x2 + 1) * -1)) || (x > (dispWin.x2 + 1)) || (y < ((dispWin.y2 + 1) * -1)) || (y > (dispWin.y2 + 1))) { |
|
2584 sprintf(err_buf, "out of display area (%d,%d", x, y); |
|
2585 err = -10; |
|
2586 goto exit; |
|
2587 } |
|
2588 |
|
2589 // ** set display and image areas |
|
2590 if (x < dispWin.x1) { |
|
2591 disp_xstart = dispWin.x1; |
|
2592 img_xstart = -x; // image pixel line X offset |
|
2593 img_xlen += x; |
|
2594 } |
|
2595 else { |
|
2596 disp_xstart = x; |
|
2597 img_xstart = 0; |
|
2598 } |
|
2599 if (y < dispWin.y1) { |
|
2600 disp_ystart = dispWin.y1; |
|
2601 img_ystart = -y; // image pixel line Y offset |
|
2602 img_ylen += y; |
|
2603 } |
|
2604 else { |
|
2605 disp_ystart = y; |
|
2606 img_ystart = 0; |
|
2607 } |
|
2608 disp_xend = disp_xstart + img_xlen - 1; |
|
2609 disp_yend = disp_ystart + img_ylen - 1; |
|
2610 if (disp_xend > dispWin.x2) { |
|
2611 disp_xend = dispWin.x2; |
|
2612 img_xlen = disp_xend - disp_xstart + 1; |
|
2613 } |
|
2614 if (disp_yend > dispWin.y2) { |
|
2615 disp_yend = dispWin.y2; |
|
2616 img_ylen = disp_yend - disp_ystart + 1; |
|
2617 } |
|
2618 |
|
2619 if ((img_xlen < 8) || (img_ylen < 8) || (img_xstart >= (img_xsize-2)) || ((img_ysize - img_ystart) < 2)) { |
|
2620 sprintf(err_buf, "image too small"); |
|
2621 err = -11; |
|
2622 goto exit; |
|
2623 } |
|
2624 |
|
2625 // ** Allocate memory for 2 lines of image pixels |
|
2626 line_buf[0] = heap_caps_malloc(img_xsize*3, MALLOC_CAP_DMA); |
|
2627 if (line_buf[0] == NULL) { |
|
2628 sprintf(err_buf, "allocating line buffer #1"); |
|
2629 err=-12; |
|
2630 goto exit; |
|
2631 } |
|
2632 |
|
2633 line_buf[1] = heap_caps_malloc(img_xsize*3, MALLOC_CAP_DMA); |
|
2634 if (line_buf[1] == NULL) { |
|
2635 sprintf(err_buf, "allocating line buffer #2"); |
|
2636 err=-13; |
|
2637 goto exit; |
|
2638 } |
|
2639 |
|
2640 if (scale) { |
|
2641 // Allocate memory for scale buffer |
|
2642 rd_len = img_xlen * 3 * scale_pix; |
|
2643 scale_buf = malloc(rd_len*scale_pix); |
|
2644 if (scale_buf == NULL) { |
|
2645 sprintf(err_buf, "allocating scale buffer"); |
|
2646 err=-14; |
|
2647 goto exit; |
|
2648 } |
|
2649 } |
|
2650 else rd_len = img_xlen * 3; |
|
2651 |
|
2652 // ** ***************************************************** ** |
|
2653 // ** BMP images are stored in file from LAST to FIRST line ** |
|
2654 // ** ***************************************************** ** |
|
2655 |
|
2656 /* Used variables: |
|
2657 img_xsize horizontal image size in pixels |
|
2658 img_ysize number of image lines |
|
2659 img_xlen image display horizontal scaled size in pixels |
|
2660 img_ylen image display vertical scaled size in pixels |
|
2661 img_xstart first pixel in line to be displayed |
|
2662 img_ystart first image line to be displayed |
|
2663 img_xlen number of pixels in image line to be displayed, starting with 'img_xstart' |
|
2664 img_ylen number of lines in image to be displayed, starting with 'img_ystart' |
|
2665 rd_len length of color data which are read from image line in bytes |
|
2666 */ |
|
2667 |
|
2668 // Set position in image to the first color data (beginning of the LAST line) |
|
2669 img_pos += (img_ystart * (img_xsize*3)); |
|
2670 if (fhndl) { |
|
2671 if (fseek(fhndl, img_pos, SEEK_SET) != 0) { |
|
2672 sprintf(err_buf, "file seek at %d", img_pos); |
|
2673 err = -15; |
|
2674 goto exit; |
|
2675 } |
|
2676 } |
|
2677 |
|
2678 if (image_debug) printf("BMP: image size: (%d,%d) scale: %d disp size: (%d,%d) img xofs: %d img yofs: %d at: %d,%d; line buf: 2* %d scale buf: %d\r\n", |
|
2679 img_xsize, img_ysize, scale_pix, img_xlen, img_ylen, img_xstart, img_ystart, disp_xstart, disp_ystart, img_xsize*3, ((scale) ? (rd_len*scale_pix) : 0)); |
|
2680 |
|
2681 // * Select the display |
|
2682 disp_select(); |
|
2683 |
|
2684 while ((disp_yend >= disp_ystart) && ((img_pos + (img_xsize*3)) <= size)) { |
|
2685 if (img_pos > size) { |
|
2686 sprintf(err_buf, "EOF reached: %d > %d", img_pos, size); |
|
2687 err = -16; |
|
2688 goto exit1; |
|
2689 } |
|
2690 if (scale == 0) { |
|
2691 // Read the line of color data into color buffer |
|
2692 if (fhndl) { |
|
2693 i = fread(line_buf[lb_idx], 1, img_xsize*3, fhndl); // read line from file |
|
2694 if (i != (img_xsize*3)) { |
|
2695 sprintf(err_buf, "file read at %d (%d<>%d)", img_pos, i, img_xsize*3); |
|
2696 err = -16; |
|
2697 goto exit1; |
|
2698 } |
|
2699 } |
|
2700 else memcpy(line_buf[lb_idx], imgbuf+img_pos, img_xsize*3); |
|
2701 |
|
2702 if (img_xstart > 0) memmove(line_buf[lb_idx], line_buf[lb_idx]+(img_xstart*3), rd_len); |
|
2703 // Convert colors BGR-888 (BMP) -> RGB-888 (DISPLAY) === |
|
2704 for (i=0; i < rd_len; i += 3) { |
|
2705 tmpc = line_buf[lb_idx][i+2] & 0xfc; // save R |
|
2706 line_buf[lb_idx][i+2] = line_buf[lb_idx][i] & 0xfc; // B -> R |
|
2707 line_buf[lb_idx][i] = tmpc; // R -> B |
|
2708 line_buf[lb_idx][i+1] &= 0xfc; // G |
|
2709 } |
|
2710 img_pos += (img_xsize*3); |
|
2711 } |
|
2712 else { |
|
2713 // scale image, read 'scale_pix' lines and find the average color |
|
2714 for (scan_lines=0; scan_lines<scale_pix; scan_lines++) { |
|
2715 if (img_pos > size) break; |
|
2716 if (fhndl) { |
|
2717 i = fread(line_buf[lb_idx], 1, img_xsize*3, fhndl); // read line from file |
|
2718 if (i != (img_xsize*3)) { |
|
2719 sprintf(err_buf, "file read at %d (%d<>%d)", img_pos, i, img_xsize*3); |
|
2720 err = -17; |
|
2721 goto exit1; |
|
2722 } |
|
2723 } |
|
2724 else memcpy(line_buf[lb_idx], imgbuf+img_pos, img_xsize*3); |
|
2725 img_pos += (img_xsize*3); |
|
2726 |
|
2727 // copy only data which are displayed to scale buffer |
|
2728 memcpy(scale_buf + (rd_len * scan_lines), line_buf[lb_idx]+img_xstart, rd_len); |
|
2729 } |
|
2730 |
|
2731 // Populate display line buffer |
|
2732 for (int n=0;n<(img_xlen*3);n += 3) { |
|
2733 memset(co, 0, sizeof(co)); // initialize color sum |
|
2734 npix = 0; // initialize number of pixels in scale rectangle |
|
2735 |
|
2736 // sum all pixels in scale rectangle |
|
2737 for (int sc_line=0; sc_line<scan_lines; sc_line++) { |
|
2738 // Get colors position in scale buffer |
|
2739 img_pix_pos = (rd_len * sc_line) + (n * scale_pix); |
|
2740 |
|
2741 for (int sc_col=0; sc_col<scale_pix; sc_col++) { |
|
2742 co[0] += scale_buf[img_pix_pos]; |
|
2743 co[1] += scale_buf[img_pix_pos + 1]; |
|
2744 co[2] += scale_buf[img_pix_pos + 2]; |
|
2745 npix++; |
|
2746 } |
|
2747 } |
|
2748 // Place the average in display buffer, convert BGR-888 (BMP) -> RGB-888 (DISPLAY) |
|
2749 line_buf[lb_idx][n+2] = (uint8_t)(co[0] / npix); // B |
|
2750 line_buf[lb_idx][n+1] = (uint8_t)(co[1] / npix); // G |
|
2751 line_buf[lb_idx][n] = (uint8_t)(co[2] / npix); // R |
|
2752 } |
|
2753 } |
|
2754 |
|
2755 wait_trans_finish(1); |
|
2756 send_data(disp_xstart, disp_yend, disp_xend, disp_yend, img_xlen, (color_t *)line_buf[lb_idx]); |
|
2757 lb_idx = (lb_idx + 1) & 1; // change buffer |
|
2758 |
|
2759 disp_yend--; |
|
2760 } |
|
2761 err = 0; |
|
2762 exit1: |
|
2763 disp_deselect(); |
|
2764 exit: |
|
2765 if (scale_buf) free(scale_buf); |
|
2766 if (line_buf[0]) free(line_buf[0]); |
|
2767 if (line_buf[1]) free(line_buf[1]); |
|
2768 if (fhndl) fclose(fhndl); |
|
2769 if ((err) && (image_debug)) printf("Error: %d [%s]\r\n", err, err_buf); |
|
2770 |
|
2771 return err; |
|
2772 } |
|
2773 |
|
2774 |
|
2775 // ============= Touch panel functions ========================================= |
2267 // ============= Touch panel functions ========================================= |
2776 |
2268 |
2777 #if USE_TOUCH == TOUCH_TYPE_XPT2046 |
2269 #if USE_TOUCH == TOUCH_TYPE_XPT2046 |
2778 //------------------------------------------------------- |
2270 //------------------------------------------------------- |
2779 static int tp_get_data_xpt2046(uint8_t type, int samples) |
2271 static int tp_get_data_xpt2046(uint8_t type, int samples) |