summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkImgPPM.c58
-rw-r--r--tests/imgPPM.test11
2 files changed, 48 insertions, 21 deletions
diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c
index edd1b71..d9c06ab 100644
--- a/generic/tkImgPPM.c
+++ b/generic/tkImgPPM.c
@@ -141,7 +141,7 @@ FileReadPPM(
* image being read. */
{
int fileWidth, fileHeight, maxIntensity;
- int nLines, nBytes, h, type, count;
+ int nLines, nBytes, h, type, count, bytesPerChannel = 1;
unsigned char *pixelPtr;
Tk_PhotoImageBlock block;
@@ -158,12 +158,14 @@ FileReadPPM(
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
return TCL_ERROR;
}
- if ((maxIntensity <= 0) || (maxIntensity >= 256)) {
+ if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"PPM image file \"%s\" has bad maximum intensity value %d",
fileName, maxIntensity));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL);
return TCL_ERROR;
+ } else if (maxIntensity > 0x00ff) {
+ bytesPerChannel = 2;
}
if ((srcX + width) > fileWidth) {
@@ -173,20 +175,20 @@ FileReadPPM(
height = fileHeight - srcY;
}
if ((width <= 0) || (height <= 0)
- || (srcX >= fileWidth) || (srcY >= fileHeight)) {
+ || (srcX >= fileWidth) || (srcY >= fileHeight)) {
return TCL_OK;
}
if (type == PGM) {
- block.pixelSize = 1;
+ block.pixelSize = 1 * bytesPerChannel;
block.offset[0] = 0;
block.offset[1] = 0;
block.offset[2] = 0;
} else {
- block.pixelSize = 3;
+ block.pixelSize = 3 * bytesPerChannel;
block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
+ block.offset[1] = 1 * bytesPerChannel;
+ block.offset[2] = 2 * bytesPerChannel;
}
block.offset[3] = 0;
block.width = width;
@@ -228,12 +230,21 @@ FileReadPPM(
ckfree(pixelPtr);
return TCL_ERROR;
}
- if (maxIntensity != 255) {
+ if (maxIntensity < 0x00ff) {
unsigned char *p;
for (p = pixelPtr; count > 0; count--, p++) {
*p = (((int) *p) * 255)/maxIntensity;
}
+ } else if (maxIntensity > 0x00ff) {
+ unsigned char *p;
+ unsigned int value;
+
+ for (p = pixelPtr; count > 0; count--, p += 2) {
+ value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
+ value = value * 255 / maxIntensity;
+ p[0] = p[1] = (unsigned char) value;
+ }
}
block.height = nLines;
if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
@@ -478,7 +489,7 @@ StringReadPPM(
* image being read. */
{
int fileWidth, fileHeight, maxIntensity;
- int nLines, nBytes, h, type, count, dataSize;
+ int nLines, nBytes, h, type, count, dataSize, bytesPerChannel = 2;
unsigned char *pixelPtr, *dataBuffer;
Tk_PhotoImageBlock block;
@@ -496,12 +507,14 @@ StringReadPPM(
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "DIMENSIONS", NULL);
return TCL_ERROR;
}
- if ((maxIntensity <= 0) || (maxIntensity >= 256)) {
+ if ((maxIntensity <= 0) || (maxIntensity > 0xffff)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"PPM image data has bad maximum intensity value %d",
maxIntensity));
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "INTENSITY", NULL);
return TCL_ERROR;
+ } else if (maxIntensity > 0x00ff) {
+ bytesPerChannel = 2;
}
if ((srcX + width) > fileWidth) {
@@ -516,15 +529,15 @@ StringReadPPM(
}
if (type == PGM) {
- block.pixelSize = 1;
+ block.pixelSize = 1 * bytesPerChannel;
block.offset[0] = 0;
block.offset[1] = 0;
block.offset[2] = 0;
} else {
- block.pixelSize = 3;
+ block.pixelSize = 3 * bytesPerChannel;
block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
+ block.offset[1] = 1 * bytesPerChannel;
+ block.offset[2] = 2 * bytesPerChannel;
}
block.offset[3] = 0;
block.width = width;
@@ -535,7 +548,7 @@ StringReadPPM(
dataSize -= srcY * block.pitch;
}
- if (maxIntensity == 255) {
+ if (maxIntensity == 0x00ff) {
/*
* We have all the data in memory, so write everything in one go.
*/
@@ -582,8 +595,19 @@ StringReadPPM(
Tcl_SetErrorCode(interp, "TK", "IMAGE", "PPM", "TRUNCATED", NULL);
return TCL_ERROR;
}
- for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
- *p = (((int) *dataBuffer) * 255)/maxIntensity;
+ if (maxIntensity < 0x00ff) {
+ for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
+ *p = (((int) *dataBuffer) * 255)/maxIntensity;
+ }
+ } else {
+ unsigned char *p;
+ unsigned int value;
+
+ for (p = pixelPtr; count > 0; count--, p += 2) {
+ value = ((unsigned int) p[0]) * 256 + ((unsigned int) p[1]);
+ value = value * 255 / maxIntensity;
+ p[0] = p[1] = (unsigned char) value;
+ }
}
dataSize -= nBytes;
block.height = nLines;
diff --git a/tests/imgPPM.test b/tests/imgPPM.test
index 456427f..b5955df 100644
--- a/tests/imgPPM.test
+++ b/tests/imgPPM.test
@@ -21,7 +21,7 @@ proc put {file data} {
puts -nonewline $f $data
close $f
}
-
+
test imgPPM-1.1 {FileReadPPM procedure} -body {
put test.ppm "P6\n0 256\n255\nabcdef"
image create photo p1 -file test.ppm
@@ -39,9 +39,9 @@ test imgPPM-1.4 {FileReadPPM procedure} -body {
image create photo p1 -file test.ppm
} -returnCodes error -result {PPM image file "test.ppm" has dimension(s) <= 0}
test imgPPM-1.5 {FileReadPPM procedure} -body {
- put test.ppm "P6\n10 20\n256\nabcdef"
+ put test.ppm "P6\n10 20\n100000\nabcdef"
image create photo p1 -file test.ppm
-} -returnCodes error -result {PPM image file "test.ppm" has bad maximum intensity value 256}
+} -returnCodes error -result {PPM image file "test.ppm" has bad maximum intensity value 100000}
test imgPPM-1.6 {FileReadPPM procedure} -body {
put test.ppm "P6\n10 20\n0\nabcdef"
image create photo p1 -file test.ppm
@@ -161,7 +161,7 @@ test imgPPM-4.1 {StringReadPPM procedure, data too short [Bug 1822391]} -body {
} -cleanup {
image delete I
} -returnCodes error -result {truncated PPM data}
-
+
imageFinish
# cleanup
@@ -169,3 +169,6 @@ catch {file delete test.ppm}
cleanupTests
return
+# Local Variables:
+# mode: tcl
+# End: