ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CV/CV.xs
(Generate patch)

Comparing CV/CV.xs (file contents):
Revision 1.58 by root, Mon Jan 4 04:49:04 2021 UTC vs.
Revision 1.63 by root, Sun Nov 28 23:26:51 2021 UTC

418 CODE: 418 CODE:
419{ 419{
420 STRLEN data_len; 420 STRLEN data_len;
421 U8 *data = SvPVbyte (image_data, data_len); 421 U8 *data = SvPVbyte (image_data, data_len);
422 static const unsigned char jxl_header[] = { 422 static const unsigned char jxl_header[] = {
423 0, 0, 0, 0x0c, 0x4a, 0x58, 0x4c, 0x20, 423 0, 0, 0, 0x0c, 0x4a, 0x58, 0x4c, 0x20, 0x0d, 0xa, 0x87, 0x0a
424 0x0d, 0xa, 0x87, 0x0a, 0, 0, 0, 0x14,
425 0x66, 0x74, 0x79, 0x70, 0x6a, 0x78, 0x6c, 0x20,
426 0, 0, 0, 0, 0x6a, 0x78, 0x6c, 0x20,
427 }; 424 };
428 425
429 if (data_len >= 20 426 if (data_len >= 20
430 && data[0] == 0xff 427 && data[0] == 0xff
431 && data[1] == 0xd8 428 && data[1] == 0xd8
450 && data[ 5] == 0x0a 447 && data[ 5] == 0x0a
451 && data[ 6] == 0x1a 448 && data[ 6] == 0x1a
452 && data[ 7] == 0x0a) 449 && data[ 7] == 0x0a)
453 RETVAL = "image/png"; 450 RETVAL = "image/png";
454 else if (data_len >= sizeof (jxl_header) && memcmp (data, jxl_header, sizeof (jxl_header)) == 0) 451 else if (data_len >= sizeof (jxl_header) && memcmp (data, jxl_header, sizeof (jxl_header)) == 0)
452 RETVAL = "image/jxl"; // todo: might want to use JxlSignatureCheck
453 else if (data_len >= 2
454 && data[0] == 0xff
455 && data[1] == 0x0a)
455 RETVAL = "image/jxl"; 456 RETVAL = "image/jxl";
457 else if (data_len >= 13
458 && data[0] == 'G'
459 && data[1] == 'I'
460 && data[2] == 'F'
461 && data[3] == '8'
462 //&& (data[4] == '7' || data[4] == '9')
463 && data[5] == 'a')
464 {
465 RETVAL = "image/gif";
466
467 // now see if its animated - we require the netscape application header for this
468 int ofs = 13;
469
470 if (data[10] & 0x80)
471 ofs += (1 << ((data[10] & 7) + 1)) * 3;
472
473 if (data_len >= ofs + 2 + 1 + 11)
474 {
475
476 // skip a graphic control extension block. we assume
477 // there is at most one such block - while the NAB
478 // has to come firstz, some files do not obey this
479 if (data[ofs] == 0x21 && data[ofs + 1] == 0xf9)
480 ofs += 3 + data[ofs + 2] + 1;
481
482 if (data_len >= ofs + 2 + 1 + 11)
483 if (!memcmp (data + ofs, "\x21\xff\x0bNETSCAPE2.0", sizeof ("\x21\xff\x0bNETSCAPE2.0") - 1))
484 RETVAL = "video/gif";
485 }
486 }
487
456 else 488 else
457 XSRETURN_UNDEF; 489 XSRETURN_UNDEF;
458} 490}
459 OUTPUT: 491 OUTPUT:
460 RETVAL 492 RETVAL
551GdkPixbuf_noinc * 583GdkPixbuf_noinc *
552decode_jxl (SV *image_data, int thumbnail = 0, int iw = 0, int ih = 0) 584decode_jxl (SV *image_data, int thumbnail = 0, int iw = 0, int ih = 0)
553 CODE: 585 CODE:
554{ 586{
555#if JXL 587#if JXL
556 JxlDecoder *dec = JxlDecoderCreate (0); 588 JxlDecoder *dec;
557 JxlBasicInfo info; 589 JxlBasicInfo info;
558 const uint8_t *next_in = (uint8_t *)SvPVbyte_nolen (image_data); 590 const uint8_t *next_in = (uint8_t *)SvPVbyte_nolen (image_data);
559 size_t avail_in = SvCUR (image_data); 591 size_t avail_in = SvCUR (image_data);
560 const char *error = 0; 592 const char *error = 0;
593 JxlDecoderStatus status;
561 void *runner = 0; 594 void *runner = 0;
562 struct bmff_box box; 595 struct bmff_box box;
563 596
597 RETVAL = 0;
598
564 perlinterp_release (); 599 perlinterp_release ();
565 600
566 RETVAL = 0; 601 dec = JxlDecoderCreate (0);
567 602
568 error = "JxlDecoderCreate failed"; 603 error = "JxlDecoderCreate failed";
569 if (!dec) 604 if (!dec)
570 goto done; 605 goto done;
571 606
572 runner = JxlThreadParallelRunnerCreate (0, JxlThreadParallelRunnerDefaultNumWorkerThreads ()); 607 runner = JxlThreadParallelRunnerCreate (0, JxlThreadParallelRunnerDefaultNumWorkerThreads ());
573 608
609 status = JxlDecoderSetParallelRunner (dec, JxlThreadParallelRunner, runner);
574 error = "JxlDecoderSetParallelRunner failed"; 610 error = "JxlDecoderSetParallelRunner failed";
575 if (JxlDecoderSetParallelRunner (dec, JxlThreadParallelRunner, runner) != JXL_DEC_SUCCESS) 611 if (status != JXL_DEC_SUCCESS)
576 goto done; 612 goto done;
577 613
578 error = "JxlDecoderSubscribeEvents failed"; 614 error = "JxlDecoderSubscribeEvents failed";
579 if (JxlDecoderSubscribeEvents (dec, JXL_DEC_FULL_IMAGE | 0xffc0) != JXL_DEC_SUCCESS) 615 status = JxlDecoderSubscribeEvents (dec, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
616 if (status != JXL_DEC_SUCCESS)
580 goto done; 617 goto done;
581 618
619 status = JxlDecoderSetInput (dec, next_in, avail_in);
620 error = "JxlDecoderSetInput failed";
621 if (status != JXL_DEC_SUCCESS)
622 goto done;
623
582 for (;;) 624 for (;;)
583 { 625 {
584 JxlDecoderStatus status = JxlDecoderProcessInput (dec, &next_in, &avail_in); 626 status = JxlDecoderProcessInput (dec);
585 627
586 printf ("status %d\n",status);
587
588 switch (status) 628 switch (status)
589 { 629 {
630 case JXL_DEC_FULL_IMAGE:
631 error = 0;
632 goto done;
633
590 case JXL_DEC_ERROR: 634 case JXL_DEC_ERROR:
591 error = "JxlDecoderProcessInput failed"; 635 error = "JxlDecoderProcessInput failed";
592 goto done; 636 goto done;
593 637
594 case JXL_DEC_NEED_MORE_INPUT: 638 case JXL_DEC_NEED_MORE_INPUT:
595 error = "incomplete file"; 639 error = "incomplete file";
596 goto done; 640 goto done;
597 641
598 case JXL_DEC_SUCCESS: 642 case JXL_DEC_SUCCESS:
643 error = "incomplete decode";
599 goto done; 644 goto done;
600 645
601 case JXL_DEC_NEED_IMAGE_OUT_BUFFER: 646 case JXL_DEC_BASIC_INFO:
602 { 647 {
648 status = JxlDecoderGetBasicInfo (dec, &info);
603 error = "JxlDecoderGetBasicInfo failed"; 649 error = "JxlDecoderGetBasicInfo failed";
604 if (JxlDecoderGetBasicInfo (dec, &info) != JXL_DEC_SUCCESS) 650 if (status != JXL_DEC_SUCCESS)
605 goto done; 651 goto done;
606 652
607 RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!info.alpha_bits, 8, info.xsize, info.ysize); 653 RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!info.alpha_bits, 8, info.xsize, info.ysize);
608 error = "unable to allocate pixbuf"; 654 error = "unable to allocate pixbuf";
609 if (!RETVAL) 655 if (!RETVAL)
614 JXL_TYPE_UINT8, 660 JXL_TYPE_UINT8,
615 JXL_NATIVE_ENDIAN, 661 JXL_NATIVE_ENDIAN,
616 gdk_pixbuf_get_rowstride (RETVAL) 662 gdk_pixbuf_get_rowstride (RETVAL)
617 }; 663 };
618 664
665 // cannot use gdk_pixbuf_get_byte_length because that does
666 // not return the size of the buffer, but the size of the buffer without
667 // the last padding bytes. the internal buffer is rowstride * ysize,
668 // and this is what the jxl decoder needs. none of this is documented
669 // in either library, of course.
670
671 status = JxlDecoderSetImageOutBuffer (
672 dec,
673 &format,
674 gdk_pixbuf_get_pixels (RETVAL),
675 gdk_pixbuf_get_rowstride (RETVAL) * info.ysize
676 );
619 error = "JxlDecoderSetImageOutBuffer failed"; 677 error = "JxlDecoderSetImageOutBuffer failed";
620 if (JxlDecoderSetImageOutBuffer (
621 dec,
622 &format,
623 gdk_pixbuf_get_pixels (RETVAL),
624 gdk_pixbuf_get_byte_length (RETVAL)
625 ) != JXL_DEC_SUCCESS) 678 if (status != JXL_DEC_SUCCESS)
626 goto done; 679 goto done;
627 } 680 }
628 break; 681 break;
629 682
630 default: 683 default:
645 if (error) 698 if (error)
646 { 699 {
647 if (RETVAL) 700 if (RETVAL)
648 g_object_unref (RETVAL); 701 g_object_unref (RETVAL);
649 702
650 croak ("load_jxl: %s", error); 703 croak ("load_jxl: %s (status %d)", error, status);
651 } 704 }
652#else 705#else
653 croak ("load_jxl: jpeg-xl not enabled at compile time"); 706 croak ("load_jxl: jpeg-xl not enabled at compile time");
654#endif 707#endif
655} 708}
847 CODE: 900 CODE:
848{ 901{
849 STRLEN plen; 902 STRLEN plen;
850 U8 *path = (U8 *)SvPV (pathsv, plen); 903 U8 *path = (U8 *)SvPV (pathsv, plen);
851 U8 *pend = path + plen; 904 U8 *pend = path + plen;
852 U8 dst [plen * 6 * 3], *dstp = dst; 905 U8 dst [plen * 8 * 3], *dstp = dst;
853 906
854 while (path < pend) 907 while (path < pend)
855 { 908 {
856 U8 ch = *path; 909 U8 ch = *path;
857 910
859 *dstp++ = *path++; 912 *dstp++ = *path++;
860 else if (ch >= 'A' && ch <= 'Z') 913 else if (ch >= 'A' && ch <= 'Z')
861 *dstp++ = *path++ + ('a' - 'A'); 914 *dstp++ = *path++ + ('a' - 'A');
862 else if (ch >= '0' && ch <= '9') 915 else if (ch >= '0' && ch <= '9')
863 { 916 {
917 /* version sort, up to 8 digits */
864 STRLEN el, nl = 0; 918 STRLEN el, nl = 0;
865 while (*path >= '0' && *path <= '9' && path < pend) 919 while (*path >= '0' && *path <= '9' && path < pend)
866 path++, nl++; 920 path++, nl++;
867 921
868 for (el = nl; el < 6; el++) 922 for (el = nl; el < 8; el++)
869 *dstp++ = '0'; 923 *dstp++ = '0';
870 924
871 memcpy (dstp, path - nl, nl); 925 memcpy (dstp, path - nl, nl);
872 dstp += nl; 926 dstp += nl;
873 } 927 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines