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

Comparing CV/CV.xs (file contents):
Revision 1.62 by root, Sun Jul 25 11:32:46 2021 UTC vs.
Revision 1.64 by root, Wed Dec 1 03:32:40 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";
456 else if (data_len >= 13 457 else if (data_len >= 13
457 && data[0] == 'G' 458 && data[0] == 'G'
458 && data[1] == 'I' 459 && data[1] == 'I'
459 && data[2] == 'F' 460 && data[2] == 'F'
582GdkPixbuf_noinc * 583GdkPixbuf_noinc *
583decode_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)
584 CODE: 585 CODE:
585{ 586{
586#if JXL 587#if JXL
587 JxlDecoder *dec = JxlDecoderCreate (0); 588 JxlDecoder *dec;
588 JxlBasicInfo info; 589 JxlBasicInfo info;
589 const uint8_t *next_in = (uint8_t *)SvPVbyte_nolen (image_data); 590 const uint8_t *next_in = (uint8_t *)SvPVbyte_nolen (image_data);
590 size_t avail_in = SvCUR (image_data); 591 size_t avail_in = SvCUR (image_data);
591 const char *error = 0; 592 const char *error = 0;
593 JxlDecoderStatus status;
592 void *runner = 0; 594 void *runner = 0;
593 struct bmff_box box; 595
596 RETVAL = 0;
594 597
595 perlinterp_release (); 598 perlinterp_release ();
596 599
597 RETVAL = 0; 600 dec = JxlDecoderCreate (0);
598 601
599 error = "JxlDecoderCreate failed"; 602 error = "JxlDecoderCreate failed";
600 if (!dec) 603 if (!dec)
601 goto done; 604 goto done;
602 605
603 runner = JxlThreadParallelRunnerCreate (0, JxlThreadParallelRunnerDefaultNumWorkerThreads ()); 606 runner = JxlThreadParallelRunnerCreate (0, JxlThreadParallelRunnerDefaultNumWorkerThreads ());
604 607
608 status = JxlDecoderSetParallelRunner (dec, JxlThreadParallelRunner, runner);
605 error = "JxlDecoderSetParallelRunner failed"; 609 error = "JxlDecoderSetParallelRunner failed";
606 if (JxlDecoderSetParallelRunner (dec, JxlThreadParallelRunner, runner) != JXL_DEC_SUCCESS) 610 if (status != JXL_DEC_SUCCESS)
607 goto done; 611 goto done;
608 612
609 error = "JxlDecoderSubscribeEvents failed"; 613 error = "JxlDecoderSubscribeEvents failed";
610 if (JxlDecoderSubscribeEvents (dec, JXL_DEC_FULL_IMAGE | JXL_DEC_BASIC_INFO) != JXL_DEC_SUCCESS) 614 status = JxlDecoderSubscribeEvents (dec, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
615 if (status != JXL_DEC_SUCCESS)
611 goto done; 616 goto done;
612 617
618 status = JxlDecoderSetInput (dec, next_in, avail_in);
613 error = "JxlDecoderSetInput failed"; 619 error = "JxlDecoderSetInput failed";
614 if (JxlDecoderSetInput (dec, next_in, avail_in) != JXL_DEC_SUCCESS) 620 if (status != JXL_DEC_SUCCESS)
615 goto done; 621 goto done;
616 622
617 for (;;) 623 for (;;)
618 { 624 {
619 JxlDecoderStatus status = JxlDecoderProcessInput (dec); 625 status = JxlDecoderProcessInput (dec);
620 626
621 printf ("status %d\n",status);
622
623 switch (status) 627 switch (status)
624 { 628 {
629 case JXL_DEC_FULL_IMAGE:
630 error = 0;
631 goto done;
632
625 case JXL_DEC_ERROR: 633 case JXL_DEC_ERROR:
626 error = "JxlDecoderProcessInput failed"; 634 error = "JxlDecoderProcessInput failed";
627 goto done; 635 goto done;
628 636
629 case JXL_DEC_NEED_MORE_INPUT: 637 case JXL_DEC_NEED_MORE_INPUT:
630 error = "incomplete file"; 638 error = "incomplete file";
631 goto done; 639 goto done;
632 640
633 case JXL_DEC_SUCCESS: 641 case JXL_DEC_SUCCESS:
642 error = "incomplete decode";
634 goto done; 643 goto done;
635 644
636 case JXL_DEC_NEED_IMAGE_OUT_BUFFER: 645 case JXL_DEC_BASIC_INFO:
637 { 646 {
647 status = JxlDecoderGetBasicInfo (dec, &info);
638 error = "JxlDecoderGetBasicInfo failed"; 648 error = "JxlDecoderGetBasicInfo failed";
639 if (JxlDecoderGetBasicInfo (dec, &info) != JXL_DEC_SUCCESS) 649 if (status != JXL_DEC_SUCCESS)
640 goto done; 650 goto done;
641 651
642 RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!info.alpha_bits, 8, info.xsize, info.ysize); 652 RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, !!info.alpha_bits, 8, info.xsize, info.ysize);
643 error = "unable to allocate pixbuf"; 653 error = "unable to allocate pixbuf";
644 if (!RETVAL) 654 if (!RETVAL)
649 JXL_TYPE_UINT8, 659 JXL_TYPE_UINT8,
650 JXL_NATIVE_ENDIAN, 660 JXL_NATIVE_ENDIAN,
651 gdk_pixbuf_get_rowstride (RETVAL) 661 gdk_pixbuf_get_rowstride (RETVAL)
652 }; 662 };
653 663
664 // cannot use gdk_pixbuf_get_byte_length because that does
665 // not return the size of the buffer, but the size of the buffer without
666 // the last padding bytes. the internal buffer is rowstride * ysize,
667 // and this is what the jxl decoder needs. none of this is documented
668 // in either library, of course.
669
670 status = JxlDecoderSetImageOutBuffer (
671 dec,
672 &format,
673 gdk_pixbuf_get_pixels (RETVAL),
674 gdk_pixbuf_get_rowstride (RETVAL) * info.ysize
675 );
654 error = "JxlDecoderSetImageOutBuffer failed"; 676 error = "JxlDecoderSetImageOutBuffer failed";
655 if (JxlDecoderSetImageOutBuffer (
656 dec,
657 &format,
658 gdk_pixbuf_get_pixels (RETVAL),
659 gdk_pixbuf_get_byte_length (RETVAL)
660 ) != JXL_DEC_SUCCESS) 677 if (status != JXL_DEC_SUCCESS)
661 goto done; 678 goto done;
662 } 679 }
663 break; 680 break;
664 681
665 default: 682 default:
680 if (error) 697 if (error)
681 { 698 {
682 if (RETVAL) 699 if (RETVAL)
683 g_object_unref (RETVAL); 700 g_object_unref (RETVAL);
684 701
685 croak ("load_jxl: %s", error); 702 croak ("load_jxl: %s (status %d)", error, status);
686 } 703 }
687#else 704#else
688 croak ("load_jxl: jpeg-xl not enabled at compile time"); 705 croak ("load_jxl: jpeg-xl not enabled at compile time");
689#endif 706#endif
690} 707}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines