summaryrefslogtreecommitdiff
path: root/coders/pcx.c
diff options
context:
space:
mode:
Diffstat (limited to 'coders/pcx.c')
-rw-r--r--coders/pcx.c83
1 files changed, 52 insertions, 31 deletions
diff --git a/coders/pcx.c b/coders/pcx.c
index 783444f..6da106c 100644
--- a/coders/pcx.c
+++ b/coders/pcx.c
@@ -356,7 +356,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
" left=%u\n"
" top=%u\n"
" right=%u\n"
- " bottom=%u\n"
+ " bottom=%u\n"
" horizontal_resolution=%u\n"
" vertical_resolution=%u\n"
" reserved=%u\n"
@@ -924,7 +924,7 @@ ModuleExport void UnregisterPCXImage(void)
%
%
*/
-static MagickPassFail WriteRLEPixels(Image *image,
+static MagickPassFail WritePCXPixels(Image *image,
PCXInfo *pcx_info,
const unsigned char *pcx_row_pixels)
{
@@ -945,16 +945,32 @@ static MagickPassFail WriteRLEPixels(Image *image,
/* For each color plane ... */
for (i=0; i < (long) pcx_info->planes; i++)
{
- previous=(*q++);
- count=1;
- /* For each column ... */
- for (x=0; x < (long) (pcx_info->bytes_per_line-1); x++)
+ if (pcx_info->encoding == 0)
{
- packet=(*q++);
- if ((packet == previous) && (count < 63))
+ for (x=0; x < (long) pcx_info->bytes_per_line; x++)
+ (void) WriteBlobByte(image,(unsigned char) (*q++));
+ }
+ else
+ {
+ previous=(*q++);
+ count=1;
+ /* For each column ... */
+ for (x=0; x < (long) (pcx_info->bytes_per_line-1); x++)
{
- count++;
- continue;
+ packet=(*q++);
+ if ((packet == previous) && (count < 63))
+ {
+ count++;
+ continue;
+ }
+ if ((count > 1) || ((previous & 0xc0) == 0xc0))
+ {
+ count|=0xc0;
+ (void) WriteBlobByte(image,count);
+ }
+ (void) WriteBlobByte(image,previous);
+ previous=packet;
+ count=1;
}
if ((count > 1) || ((previous & 0xc0) == 0xc0))
{
@@ -962,15 +978,7 @@ static MagickPassFail WriteRLEPixels(Image *image,
(void) WriteBlobByte(image,count);
}
(void) WriteBlobByte(image,previous);
- previous=packet;
- count=1;
}
- if ((count > 1) || ((previous & 0xc0) == 0xc0))
- {
- count|=0xc0;
- (void) WriteBlobByte(image,count);
- }
- (void) WriteBlobByte(image,previous);
}
return (MagickPass);
}
@@ -1029,6 +1037,9 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
unsigned long
scene;
+ const unsigned long
+ max_scenes = 1024UL;
+
ImageCharacteristics
characteristics;
@@ -1057,11 +1068,12 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
*/
write_dcx=MagickTrue;
(void) WriteBlobLSBLong(image,0x3ADE68B1L);
- page_table=MagickAllocateResourceLimitedMemory(ExtendedSignedIntegralType *,
- 1024*sizeof(ExtendedSignedIntegralType));
+ page_table=MagickAllocateResourceLimitedClearedArray(ExtendedSignedIntegralType *,
+ max_scenes+1,
+ sizeof(ExtendedSignedIntegralType));
if (page_table == (ExtendedSignedIntegralType *) NULL)
ThrowPCXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
- for (scene=0; scene < 1024; scene++)
+ for (scene=0; scene < max_scenes; scene++)
(void) WriteBlobLSBLong(image,0x00000000L);
}
adjoin=(image_info->adjoin) && (image->next != (const Image *) NULL) && (write_dcx);
@@ -1093,7 +1105,12 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
*/
pcx_info.identifier=0x0a;
pcx_info.version=5;
- pcx_info.encoding=1;
+ /* Please note that uncompressed PCX in quite rare and some applications cannot open it.
+ So the compressed PCX needs to be default. */
+ pcx_info.encoding = (image->compression==RLECompression || image->compression==UndefinedCompression) ? 1 : 0;
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "Using %s compression",
+ pcx_info.encoding == 1 ? "RLE" : "No");
pcx_info.bits_per_pixel=8;
if (characteristics.palette && characteristics.monochrome)
pcx_info.bits_per_pixel=1;
@@ -1156,11 +1173,9 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
/*
Dump colormap to file.
*/
- pcx_colormap=MagickAllocateResourceLimitedMemory(unsigned char *,3*256);
+ pcx_colormap=MagickAllocateResourceLimitedClearedArray(unsigned char *,3,256);
if (pcx_colormap == (unsigned char *) NULL)
ThrowPCXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
- for (i=0; i < (3*256); i++)
- pcx_colormap[i]=0;
q=pcx_colormap;
if (image->storage_class == PseudoClass)
for (i=0; i < (long) image->colors; i++)
@@ -1177,7 +1192,9 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
for (i=0; i < 58; i++)
(void) WriteBlobByte(image,'\0');
/* Allocate memory for one pixel row. */
- pcx_pixels=MagickAllocateResourceLimitedArray(unsigned char *,bytes_per_line,pcx_info.planes);
+ pcx_pixels=MagickAllocateResourceLimitedClearedArray(unsigned char *,
+ bytes_per_line,
+ pcx_info.planes);
if (pcx_pixels == (unsigned char *) NULL)
ThrowPCXWriterException(ResourceLimitError,MemoryAllocationFailed,image);
q=pcx_pixels;
@@ -1236,7 +1253,7 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
}
}
}
- if (WriteRLEPixels(image,&pcx_info,pcx_pixels) == MagickFail)
+ if (WritePCXPixels(image,&pcx_info,pcx_pixels) == MagickFail)
break;
if (QuantumTick(y,image->rows))
if (!MagickMonitorFormatted(y,image->rows,&image->exception,
@@ -1261,7 +1278,7 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
/* For each column ... */
for (x=0; x < (long) image->columns; x++)
*q++=indexes[x];
- if (WriteRLEPixels(image,&pcx_info,pcx_pixels) == MagickFail)
+ if (WritePCXPixels(image,&pcx_info,pcx_pixels) == MagickFail)
break;
if (image->previous == (Image *) NULL)
if (QuantumTick(y,image->rows))
@@ -1311,7 +1328,7 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
}
if (bit != 0)
*q++=byte << (8-bit);
- if (WriteRLEPixels(image,&pcx_info,pcx_pixels) == MagickFail)
+ if (WritePCXPixels(image,&pcx_info,pcx_pixels) == MagickFail)
break;
if (image->previous == (Image *) NULL)
if (QuantumTick(y,image->rows))
@@ -1329,12 +1346,12 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
if (image->next == (Image *) NULL)
break;
image=SyncNextImageInList(image);
- status=MagickMonitorFormatted(scene++,image_list_length,
+ status=MagickMonitorFormatted(scene++,Min(max_scenes,image_list_length),
&image->exception,SaveImagesText,
image->filename);
if (status == False)
break;
- if (scene >= 1023)
+ if (scene >= max_scenes-1)
break;
} while (adjoin);
if (adjoin)
@@ -1345,6 +1362,10 @@ static unsigned int WritePCXImage(const ImageInfo *image_info,Image *image)
/*
Write the DCX page table.
*/
+ if (logging && write_dcx && image_list_length > max_scenes)
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ "WARNING: DCX truncated to %lu scenes!",
+ max_scenes-1);
page_table[scene+1]=0;
(void) SeekBlob(image,0L,SEEK_SET);
(void) WriteBlobLSBLong(image,0x3ADE68B1L);