Skip to content

Commit

Permalink
Fix #789
Browse files Browse the repository at this point in the history
  • Loading branch information
hhrutter committed Jan 31, 2024
1 parent dae09eb commit 96659b7
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 24 deletions.
37 changes: 22 additions & 15 deletions pkg/pdfcpu/extract.go
Expand Up @@ -314,14 +314,7 @@ func prepareExtractImage(sd *types.StreamDict) (string, string, types.Dict, bool

return filters, lastFilter, d, imgMask
}

func img(
ctx *model.Context,
sd *types.StreamDict,
thumb, imgMask bool,
resourceID, filters, lastFilter string,
objNr int) (*model.Image, error) {

func decodeImage(ctx *model.Context, sd *types.StreamDict, filters, lastFilter string, objNr int) error {
// CCITTDecoded images / (bit) masks don't have a ColorSpace attribute, but we render image files.
if lastFilter == filter.CCITTFax {
if _, err := ctx.DereferenceDictEntry(sd.Dict, "ColorSpace"); err != nil {
Expand All @@ -332,7 +325,7 @@ func img(
if lastFilter == filter.DCT {
comp, err := ColorSpaceComponents(ctx.XRefTable, sd)
if err != nil {
return nil, err
return err
}
sd.CSComponents = comp
}
Expand All @@ -341,7 +334,7 @@ func img(

case filter.DCT, filter.JPX, filter.Flate, filter.CCITTFax, filter.RunLength:
if err := sd.Decode(); err != nil {
return nil, err
return err
}

default:
Expand All @@ -352,7 +345,25 @@ func img(
if log.CLIEnabled() {
log.CLI.Println(msg)
}
return nil, nil
return nil
}

return nil
}

func img(
ctx *model.Context,
sd *types.StreamDict,
thumb, imgMask bool,
resourceID, filters, lastFilter string,
objNr int) (*model.Image, error) {

if sd.FilterPipeline == nil {
sd.Content = sd.Raw
} else {
if err := decodeImage(ctx, sd, filters, lastFilter, objNr); err != nil {
return nil, err
}
}

r, t, err := RenderImage(ctx.XRefTable, sd, thumb, resourceID, objNr)
Expand Down Expand Up @@ -383,10 +394,6 @@ func ExtractImage(ctx *model.Context, sd *types.StreamDict, thumb bool, resource
return imageStub(ctx, sd, resourceID, filters, lastFilter, decodeParms, thumb, imgMask, objNr)
}

if sd.FilterPipeline == nil {
return nil, nil
}

return img(ctx, sd, thumb, imgMask, resourceID, filters, lastFilter, objNr)
}

Expand Down
42 changes: 33 additions & 9 deletions pkg/pdfcpu/writeImage.go
Expand Up @@ -259,7 +259,7 @@ func imageForCMYKWithoutSoftMask(im *PDFImage) image.Image {
for y := 0; y < im.h; y++ {
for x := 0; x < im.w; x++ {
img.Set(x, y, color.CMYK{C: b[i], M: b[i+1], Y: b[i+2], K: b[i+3]})
i += 4
i += im.comp
}
}

Expand Down Expand Up @@ -773,25 +773,45 @@ func renderIndexed(xRefTable *model.XRefTable, im *PDFImage, resourceName string
}

func renderDeviceN(xRefTable *model.XRefTable, im *PDFImage, resourceName string, cs types.Array) (io.Reader, string, error) {
if im.comp <= 4 {
switch im.comp {
case 1:
// Gray
return renderDeviceGrayToPNG(im, resourceName)

switch im.comp {
case 1:
case 3:
// RGB
return renderDeviceRGBToPNG(im, resourceName)

case 4:
// CMYK
return renderDeviceCMYKToTIFF(im, resourceName)
}
}

alternateCS, ok := cs[2].(types.Name)
if !ok {
return nil, "", nil
}

switch alternateCS {
case model.DeviceGrayCS:
// Gray
return renderDeviceGrayToPNG(im, resourceName)

case 3:
case model.DeviceRGBCS:
// RGB
return renderDeviceRGBToPNG(im, resourceName)

case 4:
case model.DeviceCMYKCS:
// CMYK
return renderDeviceCMYKToTIFF(im, resourceName)
}

return nil, "", nil
}

func renderFlateEncodedImage(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool, resourceName string, objNr int) (io.Reader, string, error) {
func renderImage(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool, resourceName string, objNr int) (io.Reader, string, error) {
// If color space is CMYK then write .tif else write .png

pdfImage, err := pdfImage(xRefTable, sd, thumb, objNr)
Expand Down Expand Up @@ -820,7 +840,7 @@ func renderFlateEncodedImage(xRefTable *model.XRefTable, sd *types.StreamDict, t

default:
if log.InfoEnabled() {
log.Info.Printf("renderFlateEncodedImage: objNr=%d, unsupported name colorspace %s\n", objNr, cs.String())
log.Info.Printf("renderImage: objNr=%d, unsupported name colorspace %s\n", objNr, cs.String())
}
}

Expand All @@ -846,7 +866,7 @@ func renderFlateEncodedImage(xRefTable *model.XRefTable, sd *types.StreamDict, t

default:
if log.InfoEnabled() {
log.Info.Printf("renderFlateEncodedImage: objNr=%d, unsupported array colorspace %s\n", objNr, csn)
log.Info.Printf("renderImage: objNr=%d, unsupported array colorspace %s\n", objNr, csn)
}
}

Expand Down Expand Up @@ -908,12 +928,16 @@ func renderDCTToPNG(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool
func RenderImage(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool, resourceName string, objNr int) (io.Reader, string, error) {
// Image compression is the last filter in the pipeline.

if len(sd.FilterPipeline) == 0 {
return renderImage(xRefTable, sd, thumb, resourceName, objNr)
}

f := sd.FilterPipeline[len(sd.FilterPipeline)-1].Name

switch f {

case filter.Flate, filter.CCITTFax, filter.RunLength:
return renderFlateEncodedImage(xRefTable, sd, thumb, resourceName, objNr)
return renderImage(xRefTable, sd, thumb, resourceName, objNr)

case filter.DCT:
if sd.CSComponents == 4 {
Expand Down

0 comments on commit 96659b7

Please sign in to comment.