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

Comparing CV/CV.xs (file contents):
Revision 1.59 by root, Sat Apr 10 03:32:09 2021 UTC vs.
Revision 1.68 by root, Fri May 12 02:11:10 2023 UTC

303 303
304MODULE = Gtk2::CV PACKAGE = Gtk2::CV 304MODULE = Gtk2::CV PACKAGE = Gtk2::CV
305 305
306PROTOTYPES: ENABLE 306PROTOTYPES: ENABLE
307 307
308void
309_exit (int code)
310
308# calculate the common prefix length of two strings 311# calculate the common prefix length of two strings
309# missing function in perl. really :) 312# missing function in perl. really :)
310int 313int
311common_prefix_length (a, b) 314common_prefix_length (a, b)
312 unsigned char *a = (unsigned char *)SvPVutf8_nolen ($arg); 315 unsigned char *a = (unsigned char *)SvPVutf8_nolen ($arg);
418 CODE: 421 CODE:
419{ 422{
420 STRLEN data_len; 423 STRLEN data_len;
421 U8 *data = SvPVbyte (image_data, data_len); 424 U8 *data = SvPVbyte (image_data, data_len);
422 static const unsigned char jxl_header[] = { 425 static const unsigned char jxl_header[] = {
423 0, 0, 0, 0x0c, 0x4a, 0x58, 0x4c, 0x20, 426 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 }; 427 };
428 428
429 if (data_len >= 20 429 if (data_len >= 20
430 && data[0] == 0xff 430 && data[0] == 0xff
431 && data[1] == 0xd8 431 && data[1] == 0xd8
450 && data[ 5] == 0x0a 450 && data[ 5] == 0x0a
451 && data[ 6] == 0x1a 451 && data[ 6] == 0x1a
452 && data[ 7] == 0x0a) 452 && data[ 7] == 0x0a)
453 RETVAL = "image/png"; 453 RETVAL = "image/png";
454 else if (data_len >= sizeof (jxl_header) && memcmp (data, jxl_header, sizeof (jxl_header)) == 0) 454 else if (data_len >= sizeof (jxl_header) && memcmp (data, jxl_header, sizeof (jxl_header)) == 0)
455 RETVAL = "image/jxl"; // todo: might want to use JxlSignatureCheck
456 else if (data_len >= 2
457 && data[0] == 0xff
458 && data[1] == 0x0a)
455 RETVAL = "image/jxl"; 459 RETVAL = "image/jxl";
460 else if (data_len >= 13
461 && data[0] == 'G'
462 && data[1] == 'I'
463 && data[2] == 'F'
464 && data[3] == '8'
465 //&& (data[4] == '7' || data[4] == '9')
466 && data[5] == 'a')
467 {
468 RETVAL = "image/gif";
469
470 // now see if its animated - we require the netscape application header for this
471 int ofs = 13;
472
473 if (data[10] & 0x80)
474 ofs += (1 << ((data[10] & 7) + 1)) * 3;
475
476 if (data_len >= ofs + 2 + 1 + 11)
477 {
478
479 // skip a graphic control extension block. we assume
480 // there is at most one such block - while the NAB
481 // has to come firstz, some files do not obey this
482 if (data[ofs] == 0x21 && data[ofs + 1] == 0xf9)
483 ofs += 3 + data[ofs + 2] + 1;
484
485 if (data_len >= ofs + 2 + 1 + 11)
486 if (!memcmp (data + ofs, "\x21\xff\x0bNETSCAPE2.0", sizeof ("\x21\xff\x0bNETSCAPE2.0") - 1))
487 RETVAL = "video/gif";
488 }
489 }
490 else if (data_len >= 0x8000 + 6
491 && data[0x8000+0] == 0
492 && data[0x8000+1] == (U8)'B'
493 && data[0x8000+2] == (U8)'E'
494 && data[0x8000+3] == (U8)'A'
495 && data[0x8000+4] == (U8)'0'
496 && data[0x8000+5] == (U8)'1')
497 RETVAL = "video/iso-bluray";
498 else if (data_len >= 0x8000 + 6
499 && data[0x8000+0] == 0
500 && data[0x8000+1] == (U8)'C'
501 && data[0x8000+2] == (U8)'D'
502 && data[0x8000+3] == (U8)'0'
503 && data[0x8000+4] == (U8)'0'
504 && data[0x8000+5] == (U8)'1')
505 RETVAL = "video/iso9660";
506
456 else 507 else
457 XSRETURN_UNDEF; 508 XSRETURN_UNDEF;
458} 509}
459 OUTPUT: 510 OUTPUT:
460 RETVAL 511 RETVAL
551GdkPixbuf_noinc * 602GdkPixbuf_noinc *
552decode_jxl (SV *image_data, int thumbnail = 0, int iw = 0, int ih = 0) 603decode_jxl (SV *image_data, int thumbnail = 0, int iw = 0, int ih = 0)
553 CODE: 604 CODE:
554{ 605{
555#if JXL 606#if JXL
556 JxlDecoder *dec = JxlDecoderCreate (0); 607 JxlDecoder *dec;
557 JxlBasicInfo info; 608 JxlBasicInfo info;
558 const uint8_t *next_in = (uint8_t *)SvPVbyte_nolen (image_data); 609 const uint8_t *next_in = (uint8_t *)SvPVbyte_nolen (image_data);
559 size_t avail_in = SvCUR (image_data); 610 size_t avail_in = SvCUR (image_data);
560 const char *error = 0; 611 const char *error = 0;
612 JxlDecoderStatus status;
613 static void *runner_cache;
561 void *runner = 0; 614 void *runner = 0;
562 struct bmff_box box; 615
616 RETVAL = 0;
617
618 if (runner_cache)
619 runner = runner_cache;
620 else
621 runner = JxlThreadParallelRunnerCreate (0, JxlThreadParallelRunnerDefaultNumWorkerThreads ());
622
623 runner_cache = 0;
563 624
564 perlinterp_release (); 625 perlinterp_release ();
565 626
566 RETVAL = 0; 627 dec = JxlDecoderCreate (0);
567 628
568 error = "JxlDecoderCreate failed"; 629 error = "JxlDecoderCreate failed";
569 if (!dec) 630 if (!dec)
570 goto done; 631 goto done;
571 632
572 runner = JxlThreadParallelRunnerCreate (0, JxlThreadParallelRunnerDefaultNumWorkerThreads ()); 633 status = JxlDecoderSetParallelRunner (dec, JxlThreadParallelRunner, runner);
573
574 error = "JxlDecoderSetParallelRunner failed"; 634 error = "JxlDecoderSetParallelRunner failed";
575 if (JxlDecoderSetParallelRunner (dec, JxlThreadParallelRunner, runner) != JXL_DEC_SUCCESS) 635 if (status != JXL_DEC_SUCCESS)
576 goto done; 636 goto done;
577 637
578 error = "JxlDecoderSubscribeEvents failed"; 638 error = "JxlDecoderSubscribeEvents failed";
579 if (JxlDecoderSubscribeEvents (dec, JXL_DEC_FULL_IMAGE | JXL_DEC_BASIC_INFO) != JXL_DEC_SUCCESS) 639 status = JxlDecoderSubscribeEvents (dec, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
640 if (status != JXL_DEC_SUCCESS)
580 goto done; 641 goto done;
581 642
643 status = JxlDecoderSetInput (dec, next_in, avail_in);
582 error = "JxlDecoderSetInput failed"; 644 error = "JxlDecoderSetInput failed";
583 if (JxlDecoderSetInput (dec, next_in, avail_in) != JXL_DEC_SUCCESS) 645 if (status != JXL_DEC_SUCCESS)
584 goto done; 646 goto done;
585 647
586 for (;;) 648 for (;;)
587 { 649 {
588 JxlDecoderStatus status = JxlDecoderProcessInput (dec); 650 status = JxlDecoderProcessInput (dec);
589 651
590 printf ("status %d\n",status);
591
592 switch (status) 652 switch (status)
593 { 653 {
654 case JXL_DEC_FULL_IMAGE:
655 error = 0;
656 goto done;
657
594 case JXL_DEC_ERROR: 658 case JXL_DEC_ERROR:
595 error = "JxlDecoderProcessInput failed"; 659 error = "JxlDecoderProcessInput failed";
596 goto done; 660 goto done;
597 661
598 case JXL_DEC_NEED_MORE_INPUT: 662 case JXL_DEC_NEED_MORE_INPUT:
599 error = "incomplete file"; 663 error = "incomplete file";
600 goto done; 664 goto done;
601 665
602 case JXL_DEC_SUCCESS: 666 case JXL_DEC_SUCCESS:
667 error = "incomplete decode";
603 goto done; 668 goto done;
604 669
605 case JXL_DEC_NEED_IMAGE_OUT_BUFFER: 670 case JXL_DEC_BASIC_INFO:
606 { 671 {
672 status = JxlDecoderGetBasicInfo (dec, &info);
607 error = "JxlDecoderGetBasicInfo failed"; 673 error = "JxlDecoderGetBasicInfo failed";
608 if (JxlDecoderGetBasicInfo (dec, &info) != JXL_DEC_SUCCESS) 674 if (status != JXL_DEC_SUCCESS)
609 goto done; 675 goto done;
610 676
611 RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!info.alpha_bits, 8, info.xsize, info.ysize); 677 RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!info.alpha_bits, 8, info.xsize, info.ysize);
612 error = "unable to allocate pixbuf"; 678 error = "unable to allocate pixbuf";
613 if (!RETVAL) 679 if (!RETVAL)
618 JXL_TYPE_UINT8, 684 JXL_TYPE_UINT8,
619 JXL_NATIVE_ENDIAN, 685 JXL_NATIVE_ENDIAN,
620 gdk_pixbuf_get_rowstride (RETVAL) 686 gdk_pixbuf_get_rowstride (RETVAL)
621 }; 687 };
622 688
689 // cannot use gdk_pixbuf_get_byte_length because that does
690 // not return the size of the buffer, but the size of the buffer without
691 // the last padding bytes. the internal buffer is rowstride * ysize,
692 // and this is what the jxl decoder needs. none of this is documented
693 // in either library, of course.
694
695 status = JxlDecoderSetImageOutBuffer (
696 dec,
697 &format,
698 gdk_pixbuf_get_pixels (RETVAL),
699 gdk_pixbuf_get_rowstride (RETVAL) * info.ysize
700 );
623 error = "JxlDecoderSetImageOutBuffer failed"; 701 error = "JxlDecoderSetImageOutBuffer failed";
624 if (JxlDecoderSetImageOutBuffer (
625 dec,
626 &format,
627 gdk_pixbuf_get_pixels (RETVAL),
628 gdk_pixbuf_get_byte_length (RETVAL)
629 ) != JXL_DEC_SUCCESS) 702 if (status != JXL_DEC_SUCCESS)
630 goto done; 703 goto done;
631 } 704 }
632 break; 705 break;
633 706
634 default: 707 default:
639 712
640 done: 713 done:
641 if (dec) 714 if (dec)
642 JxlDecoderDestroy (dec); 715 JxlDecoderDestroy (dec);
643 716
717 perlinterp_acquire ();
718
644 if (runner) 719 if (runner_cache)
645 JxlThreadParallelRunnerDestroy (runner); 720 JxlThreadParallelRunnerDestroy (runner);
646 721
647 perlinterp_acquire (); 722 runner_cache = runner;
648 723
649 if (error) 724 if (error)
650 { 725 {
651 if (RETVAL) 726 if (RETVAL)
652 g_object_unref (RETVAL); 727 g_object_unref (RETVAL);
653 728
654 croak ("load_jxl: %s", error); 729 croak ("load_jxl: %s (status %d)", error, status);
655 } 730 }
656#else 731#else
657 croak ("load_jxl: jpeg-xl not enabled at compile time"); 732 croak ("load_jxl: jpeg-xl not enabled at compile time");
658#endif 733#endif
659} 734}
851 CODE: 926 CODE:
852{ 927{
853 STRLEN plen; 928 STRLEN plen;
854 U8 *path = (U8 *)SvPV (pathsv, plen); 929 U8 *path = (U8 *)SvPV (pathsv, plen);
855 U8 *pend = path + plen; 930 U8 *pend = path + plen;
856 U8 dst [plen * 6 * 3], *dstp = dst; 931 U8 dst [plen * 8 * 3], *dstp = dst;
857 932
858 while (path < pend) 933 while (path < pend)
859 { 934 {
860 U8 ch = *path; 935 U8 ch = *path;
861 936
863 *dstp++ = *path++; 938 *dstp++ = *path++;
864 else if (ch >= 'A' && ch <= 'Z') 939 else if (ch >= 'A' && ch <= 'Z')
865 *dstp++ = *path++ + ('a' - 'A'); 940 *dstp++ = *path++ + ('a' - 'A');
866 else if (ch >= '0' && ch <= '9') 941 else if (ch >= '0' && ch <= '9')
867 { 942 {
943 /* version sort, up to 8 digits */
868 STRLEN el, nl = 0; 944 STRLEN el, nl = 0;
869 while (*path >= '0' && *path <= '9' && path < pend) 945 while (*path >= '0' && *path <= '9' && path < pend)
870 path++, nl++; 946 path++, nl++;
871 947
872 for (el = nl; el < 6; el++) 948 for (el = nl; el < 8; el++)
873 *dstp++ = '0'; 949 *dstp++ = '0';
874 950
875 memcpy (dstp, path - nl, nl); 951 memcpy (dstp, path - nl, nl);
876 dstp += nl; 952 dstp += nl;
877 } 953 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines