use feature 'say';
use strict;
use warnings;
use utf8;
use open IN => ':raw', OUT => ':raw';
use Encode ( 'decode', 'encode' );
my ( $filename_in, $filename_out ) = @ARGV;
if ( ( not defined $filename_in ) || ( not defined $filename_out ) ) {
    die "perl 修复早期青苹果pdf书签.pl <input.pdf> <out.pdf>\n";
}
open my $fh1, "<", $filename_in or die $!;
my $pdf_bin = do { local $/; <$fh1>; };
close $fh1;

sub deal_with_obj {
    my $obj = $_[0];
    if ( ( $obj =~ m/\/Title \(([^\n]+)\)/s ) && ( $obj =~ m/\/First |\/Parent / ) ) {
        $obj =~ m/\/Title \(([^\n]+)\)/s;
        my $title = $1;
        $title =~ s/\r|\n//g;
        if ( $title =~ m/\A\x{ff}\x{fe}/ ) {
            #say 'fffe';
            $title =~ s/\A\x{ff}\x{fe}//;
            $title =~ s/\\n/\n/g;
            $title =~ s/\\r/\r/g;
            $title =~ s/\\t/\t/g;
            $title =~ s/\\(.)/$1/g;
            my $out_str_escaped = "<" . "feff" . unpack( 'H*', $title ) . ">";
            $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
        }
        elsif ( $title =~ m/\A\x{fe}\x{ff}/ ) {
            #say 'feff';
            $title =~ s/\A\x{fe}\x{ff}//;
            $title =~ s/\\n/\n/g;
            $title =~ s/\\r/\r/g;
            $title =~ s/\\t/\t/g;
            $title =~ s/\\(.)/$1/g;
            my $out_str_escaped = "<" . "feff" . unpack( 'H*', $title ) . ">";
            $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
        }
        elsif ( $title =~ m/\\\d{3}/ ) {
            #say '\\000';
            my $out_str = "";
            $title =~ s/\\n/\\014/g;
            $title =~ s/\\r/\\015/g;
            $title =~ s/\\t/\\011/g;
            while ( $title =~ m/(\\\d{3}|[ -'\*-\/:-\[\]-~0-9])/g ) {
                my $chars = $1;
                if ( $chars =~ m/\\\d{3}/ ) {
                    my $chars_new = $chars;
                    $chars_new =~ s/\\//;
                    my $str = pack( 'H*', sprintf( "%02x", oct( '0' . $chars_new ) ) );
                    $out_str = $out_str . $str;
                }
                else {
                    $out_str = $out_str . $chars;
                }
            }
            if ( $out_str =~ m/\A\x{ff}\x{fe}/ ) {
                $out_str =~ s/\x{ff}\x{fe}//;
            }
            else {
                $out_str = encode( 'UTF-16BE', decode( 'gbk', $out_str ) );
            }
            my $out_str_escaped = "<" . "feff" . unpack( 'H*', $out_str ) . ">";
            $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
        }
        else {
            #say 'gbk';
            $title =~ s/\\n/\n/g;
            $title =~ s/\\r/\r/g;
            $title =~ s/\\t/\t/g;
            $title =~ s/\\(.)/$1/g;
            my $out_str_encode  = encode( 'UTF-16BE', decode( 'gbk', $title ) );
            my $out_str_escaped = "<" . "feff" . unpack( 'H*', $out_str_encode ) . ">";
            $obj =~ s/\/Title \(([^\n]+)\)/"\/Title ".$out_str_escaped/es;
        }
    }
    return $obj;
}
$pdf_bin =~ s/(\d+ \d+ obj(\r|\n|\r\n).+?(\r|\n|\r\n)endobj(\r|\n|\r\n))/deal_with_obj($1)/esg;
open my $fh2, ">", $filename_out or die $!;
print $fh2 $pdf_bin;
close $fh2;

