new (PDF::Writer::External::Image)

         # File lib/pdf/writer/object/image.rb, line 157
    157:   def initialize(parent, data, image, label)
    158:     super(parent)
    159:
    160:     @data = data
    161:
    162:     @image_info = image
    163:
    164:     @info = {
    165:       'Type'    => '/XObject',
    166:       'Subtype' => '/Image',
    167:       'Width'   => image.width,
    168:       'Height'  => image.height
    169:     }
    170:
    171:     case image.format
    172:     when "JPEG"
    173:       case image.channels
    174:       when 1
    175:         @info['ColorSpace'] = '/DeviceGray'
    176:       when 4
    177:         @info['ColorSpace'] = '/DeviceCMYK'
    178:           # This should fix problems with CMYK JPEG colours inverted in
    179:           # Adobe Acrobat. Enable only if appropriate.
    180: #       @info['Decode'] = '[1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0]'
    181:       else
    182:         @info['ColorSpace'] = '/DeviceRGB'
    183:       end
    184:       @info['Filter'] = '/DCTDecode'
    185:       @info['BitsPerComponent'] = 8
    186:     when "PNG"
    187:       if image.info[:compression_method] != 0
    188:         raise TypeError, PDF::Writer::Lang[:png_unsupp_compres]
    189:       end
    190:
    191:       if image.info[:filter_method] != 0
    192:         raise TypeError, PDF::Writer::Lang[:png_unsupp_filter]
    193:       end
    194:
    195:       data = data.dup
    196:       data.extend(PDF::Writer::OffsetReader)
    197:
    198:       data.read_o(8)  # Skip the default header
    199:
    200:       ok      = true
    201:       length  = data.size
    202:       palette = ""
    203:       idat    = ""
    204:
    205:       while ok
    206:         chunk_size  = data.read_o(4).unpack("N")[0]
    207:         section     = data.read_o(4)
    208:         case section
    209:         when 'PLTE'
    210:           palette << data.read_o(chunk_size)
    211:         when 'IDAT'
    212:           idat << data.read_o(chunk_size)
    213:         when 'tRNS'
    214:             # This chunk can only occur once and it must occur after the
    215:             # PLTE chunk and before the IDAT chunk
    216:           trans = {}
    217:           case image.info[:color_type]
    218:           when 3
    219:               # Indexed colour, RGB. Each byte in this chunk is an alpha for
    220:               # the palette index in the PLTE ("palette") chunk up until the
    221:               # last non-opaque entry. Set up an array, stretching over all
    222:               # palette entries which will be 0 (opaque) or 1 (transparent).
    223:             trans[:type]  = 'indexed'
    224:             trans[:data]  = data.read_o(chunk_size).unpack("C*")
    225:           when 0
    226:               # Greyscale. Corresponding to entries in the PLTE chunk.
    227:               # Grey is two bytes, range 0 .. (2 ^ bit-depth) - 1
    228:             trans[:grayscale] = data.read_o(2).unpack("n")
    229:             trans[:type]      = 'indexed'
    230: #           trans[:data]      = data.read_o.unpack("C")
    231:           when 2
    232:               # True colour with proper alpha channel.
    233:             trans[:rgb] = data.read_o(6).unpack("nnn")
    234:           end
    235:         else
    236:           data.offset += chunk_size
    237:         end
    238:
    239:         ok = (section != "IEND")
    240:
    241:         data.read_o(4)  # Skip the CRC
    242:       end
    243:
    244:       if image.bits > 8
    245:         raise TypeError, PDF::Writer::Lang[:png_8bit_colour]
    246:       end
    247:       if image.info[:interlace_method] != 0
    248:         raise TypeError, PDF::Writer::Lang[:png_interlace]
    249:       end
    250:
    251:       ncolor  = 1
    252:       colour  = 'DeviceRGB'
    253:       case image.info[:color_type]
    254:       when 3
    255:         nil
    256:       when 2
    257:         ncolor = 3
    258:       when 0
    259:         colour = 'DeviceGray'
    260:       else
    261:         raise TypeError, PDF::Writer::Lang[:png_alpha_trans]
    262:       end
    263:
    264:       @info['Filter'] = '[/FlateDecode]'
    265:       @info['DecodeParms'] = "[<</Predictor 15 /Colors #{ncolor} /Columns #{image.width}>>]"
    266:       @info['BitsPerComponent'] = image.bits.to_s
    267:
    268:       unless palette.empty?
    269:         @info['ColorSpace']  = " [ /Indexed /DeviceRGB #{(palette.size / 3) - 1} "
    270:         contents            = PDF::Writer::Object::Contents.new(parent,
    271:                                                                 self)
    272:         contents.data       = palette
    273:         @info['ColorSpace'] << "#{contents.oid} 0 R ]"
    274:
    275:         if trans
    276:           case trans[:type]
    277:           when 'indexed'
    278:             @info['Mask']   = " [ #{trans[:data].join(' ')} ] "
    279:           end
    280:         end
    281:       else
    282:         @info['ColorSpace'] = "/#{colour}"
    283:       end
    284:
    285:       @data = idat
    286:     end
    287:
    288:     @label = label
    289:
    290:       # assign it a place in the named resource dictionary as an external
    291:       # object, according to the label passed in with it.
    292:     @parent.pages << self
    293:       # also make sure that we have the right procset object for it.
    294:     @parent.procset << 'ImageC'
    295:   end