33 |
33 |
|
34 |
34 |
require 'tempfile'
|
35 |
35 |
require 'core/rmagick'
|
|
36 |
require 'zlib'
|
36 |
37 |
|
37 |
38 |
#
|
38 |
39 |
# TCPDF Class.
|
... | ... | |
598 |
599 |
#
|
599 |
600 |
def SetCompression(compress)
|
600 |
601 |
#Set page compression
|
601 |
|
if (respond_to?('gzcompress'))
|
602 |
|
@compress = compress
|
603 |
|
else
|
604 |
|
@compress = false
|
605 |
|
end
|
|
602 |
@compress = compress
|
606 |
603 |
end
|
607 |
604 |
alias_method :set_compression, :SetCompression
|
608 |
605 |
|
... | ... | |
2417 |
2414 |
end
|
2418 |
2415 |
out(annots + ']');
|
2419 |
2416 |
end
|
|
2417 |
if @pdf_version > '1.3'
|
|
2418 |
out('/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>');
|
|
2419 |
end
|
2420 |
2420 |
out('/Contents ' + (@n+1).to_s + ' 0 R>>');
|
2421 |
2421 |
out('endobj');
|
2422 |
2422 |
#Page content
|
2423 |
|
p=(@compress) ? gzcompress(@pages[n]) : @pages[n];
|
|
2423 |
p=(@compress) ? Zlib::Deflate.deflate(@pages[n]) : @pages[n];
|
2424 |
2424 |
newobj();
|
2425 |
2425 |
out('<<' + filter + '/Length '+ p.length.to_s + '>>');
|
2426 |
2426 |
putstream(p);
|
... | ... | |
2605 |
2605 |
def putimages()
|
2606 |
2606 |
filter=(@compress) ? '/Filter /FlateDecode ' : '';
|
2607 |
2607 |
@images.each do |file, info| # was while(list(file, info)=each(@images))
|
|
2608 |
putimage(info);
|
|
2609 |
info.delete('data');
|
|
2610 |
info.delete('smask');
|
|
2611 |
end
|
|
2612 |
end
|
|
2613 |
|
|
2614 |
def putimage(info)
|
|
2615 |
if (!info['data'].nil?)
|
2608 |
2616 |
newobj();
|
2609 |
|
@images[file]['n']=@n;
|
|
2617 |
info['n']=@n;
|
2610 |
2618 |
out('<</Type /XObject');
|
2611 |
2619 |
out('/Subtype /Image');
|
2612 |
2620 |
out('/Width ' + info['w'].to_s);
|
... | ... | |
2623 |
2631 |
if (!info['f'].nil?)
|
2624 |
2632 |
out('/Filter /' + info['f']);
|
2625 |
2633 |
end
|
2626 |
|
if (!info['parms'].nil?)
|
2627 |
|
out(info['parms']);
|
|
2634 |
if (!info['dp'].nil?)
|
|
2635 |
out('/DecodeParms <<' + info['dp'] + '>>');
|
2628 |
2636 |
end
|
2629 |
2637 |
if (!info['trns'].nil? and info['trns'].kind_of?(Array))
|
2630 |
2638 |
trns='';
|
... | ... | |
2633 |
2641 |
end
|
2634 |
2642 |
out('/Mask [' + trns + ']');
|
2635 |
2643 |
end
|
|
2644 |
if (!info['smask'].nil?)
|
|
2645 |
out('/SMask ' + (@n+1).to_s + ' 0 R');
|
|
2646 |
end
|
2636 |
2647 |
out('/Length ' + info['data'].length.to_s + '>>');
|
2637 |
2648 |
putstream(info['data']);
|
2638 |
|
@images[file]['data']=nil
|
2639 |
2649 |
out('endobj');
|
|
2650 |
# Soft mask
|
|
2651 |
if (!info['smask'].nil?)
|
|
2652 |
dp = '/Predictor 15 /Colors 1 /BitsPerComponent ' + info['bpc'].to_s + ' /Columns ' + info['w'].to_s;
|
|
2653 |
smask = {'w' => info['w'], 'h' => info['h'], 'cs' => 'DeviceGray', 'bpc' => info['bpc'], 'f' => info['f'], 'dp' => dp, 'data' => info['smask']};
|
|
2654 |
putimage(smask);
|
|
2655 |
end
|
2640 |
2656 |
#Palette
|
2641 |
2657 |
if (info['cs']=='Indexed')
|
2642 |
2658 |
newobj();
|
2643 |
|
pal=(@compress) ? gzcompress(info['pal']) : info['pal'];
|
|
2659 |
filter = @compress ? '/Filter /FlateDecode ' : '';
|
|
2660 |
pal=(@compress) ? Zlib::Deflate.deflate(info['pal']) : info['pal'];
|
2644 |
2661 |
out('<<' + filter + '/Length ' + pal.length.to_s + '>>');
|
2645 |
2662 |
putstream(pal);
|
2646 |
2663 |
out('endobj');
|
... | ... | |
2931 |
2948 |
Error('16-bit depth not supported: ' + file);
|
2932 |
2949 |
end
|
2933 |
2950 |
ct=f.read(1).unpack('C')[0];
|
2934 |
|
if (ct==0)
|
|
2951 |
if (ct==0 || ct==4)
|
2935 |
2952 |
colspace='DeviceGray';
|
2936 |
|
elsif (ct==2)
|
|
2953 |
elsif (ct==2 || ct==6)
|
2937 |
2954 |
colspace='DeviceRGB';
|
2938 |
2955 |
elsif (ct==3)
|
2939 |
2956 |
colspace='Indexed';
|
2940 |
2957 |
else
|
2941 |
|
Error('Alpha channel not supported: ' + file);
|
|
2958 |
Error('Unknown color type: ' + file);
|
2942 |
2959 |
end
|
2943 |
2960 |
if (f.read(1).unpack('C')[0] != 0)
|
2944 |
2961 |
Error('Unknown compression method: ' + file);
|
... | ... | |
2950 |
2967 |
Error('Interlacing not supported: ' + file);
|
2951 |
2968 |
end
|
2952 |
2969 |
f.read(4);
|
2953 |
|
parms='/DecodeParms <</Predictor 15 /Colors ' + (ct==2 ? 3 : 1).to_s + ' /BitsPerComponent ' + bpc.to_s + ' /Columns ' + w.to_s + '>>';
|
|
2970 |
dp='/Predictor 15 /Colors ' + (colspace == 'DeviceRGB' ? 3 : 1).to_s + ' /BitsPerComponent ' + bpc.to_s + ' /Columns ' + w.to_s + '';
|
2954 |
2971 |
#Scan chunks looking for palette, transparency and image data
|
2955 |
2972 |
pal='';
|
2956 |
2973 |
trns='';
|
... | ... | |
2989 |
3006 |
if (colspace=='Indexed' and pal.empty?)
|
2990 |
3007 |
Error('Missing palette in ' + file);
|
2991 |
3008 |
end
|
2992 |
|
return {'w' => w, 'h' => h, 'cs' => colspace, 'bpc' => bpc, 'f'=>'FlateDecode', 'parms' => parms, 'pal' => pal, 'trns' => trns, 'data' => data}
|
|
3009 |
info = {'w' => w, 'h' => h, 'cs' => colspace, 'bpc' => bpc, 'f' => 'FlateDecode', 'dp' => dp, 'pal' => pal, 'trns' => trns};
|
|
3010 |
if (ct>=4)
|
|
3011 |
# Extract alpha channel
|
|
3012 |
data = Zlib::Inflate.inflate(data);
|
|
3013 |
color = ''.force_encoding(Encoding::ASCII_8BIT);
|
|
3014 |
alpha = ''.force_encoding(Encoding::ASCII_8BIT);
|
|
3015 |
if (ct==4)
|
|
3016 |
# Gray image
|
|
3017 |
length = 2*w;
|
|
3018 |
h.times{|i|
|
|
3019 |
pos = (1+length)*i;
|
|
3020 |
color += data[pos];
|
|
3021 |
alpha += data[pos];
|
|
3022 |
line = data[pos+1, length];
|
|
3023 |
color += line.gsub(/(.)./m, '\1');
|
|
3024 |
alpha += line.gsub(/.(.)/m, '\1');
|
|
3025 |
}
|
|
3026 |
else
|
|
3027 |
# RGB image
|
|
3028 |
length = 4*w;
|
|
3029 |
h.times{|i|
|
|
3030 |
pos = (1+length)*i;
|
|
3031 |
color += data[pos];
|
|
3032 |
alpha += data[pos];
|
|
3033 |
line = data[pos+1, length];
|
|
3034 |
color += line.gsub(/(.{3})./m, '\1');
|
|
3035 |
alpha += line.gsub(/.{3}(.)/m, '\1');
|
|
3036 |
}
|
|
3037 |
end
|
|
3038 |
data = Zlib::Deflate.deflate(color);
|
|
3039 |
info['smask'] = Zlib::Deflate.deflate(alpha);
|
|
3040 |
if (@pdf_version < '1.4')
|
|
3041 |
@pdf_version = '1.4';
|
|
3042 |
end
|
|
3043 |
end
|
|
3044 |
info['data'] = data;
|
|
3045 |
return info
|
2993 |
3046 |
ensure
|
2994 |
3047 |
f.close
|
2995 |
3048 |
end
|