add new code

Sat, 01 Aug 2009 12:42:34 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 01 Aug 2009 12:42:34 +0100
changeset 3
4aec27d9d4da
parent 2
81b0d2551776
child 4
5edfbd3e7a46

add new code

NOTES file | annotate | diff | revisions
src/hexdump.h file | annotate | diff | revisions
src/main.c file | annotate | diff | revisions
src/pt_image.c file | annotate | diff | revisions
src/pt_image.h file | annotate | diff | revisions
src/ptouch.c file | annotate | diff | revisions
src/ptouch.h file | annotate | diff | revisions
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/NOTES	Sat Aug 01 12:42:34 2009 +0100
     1.3 @@ -0,0 +1,1 @@
     1.4 +Hexdump code from http://sws.dett.de/mini/hexdump-c/
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/hexdump.h	Sat Aug 01 12:42:34 2009 +0100
     2.3 @@ -0,0 +1,9 @@
     2.4 +#ifndef _HEXDUMP_H
     2.5 +#define _HEXDUMP_H
     2.6 +
     2.7 +void hex_dump(void *data, int size);
     2.8 +/* dumps size bytes of *data to stdout. Looks like:
     2.9 + * [0000] 75 6E 6B 6E 6F 77 6E 20   30 FF 00 00 00 00 39 00 unknown 0.....9.
    2.10 + */
    2.11 +
    2.12 +#endif // _HEXDUMP_H
     3.1 --- a/src/main.c	Sat Aug 01 12:41:12 2009 +0100
     3.2 +++ b/src/main.c	Sat Aug 01 12:42:34 2009 +0100
     3.3 @@ -1,12 +1,49 @@
     3.4 +/**************************
     3.5 + * P-Touch PT-2450DX printer driver
     3.6 + *
     3.7 + * P. Pemberton, 2009
     3.8 + *
     3.9 + * Specs:
    3.10 + *   Printer head is 128 dots, 180dpi, for a total print area of ~18mm vertical
    3.11 + *   by however long your TZ label tape is.
    3.12 + *   Printhead size is (128/180)=0.711[.] inches, or 18.0622[.] mm
    3.13 + *   Each dot is (18.062/128) = 0.1411[.] mm
    3.14 + *   Printable area is (numdots * 0.1411) mm
    3.15 + *
    3.16 + *     Tape width   Margins      Printable area
    3.17 + *     mm    dots   mm     dots  mm    dots
    3.18 + *      6mm   42    1.0mm     7   4mm   28
    3.19 + *      9mm   63    1.0mm     7   7mm   49
    3.20 + *     12mm   85    2.0mm    14   8mm   57
    3.21 + *     18mm  127    3.0mm    21  12mm   85
    3.22 + *     24mm  170    3.0mm   128  18mm  128 ***
    3.23 + *
    3.24 + *   24mm is slightly odd. Because the printhead is only 128 dots (18mm), the
    3.25 + *   margins are enforced by this, and not the driver software. It is impossible
    3.26 + *   to print right to the edge of a 24mm label in a PT-2450DX.
    3.27 + *
    3.28 + **************************/
    3.29 +
    3.30  #include <stdio.h>
    3.31  #include <stdlib.h>
    3.32 -#include "hexdump.h"
    3.33 +#include "ptouch.h"
    3.34 +#include "pt_image.h"
    3.35  
    3.36 -#define ESC 0x1b
    3.37 +/****************************************************************************/
    3.38  
    3.39  int main(int argc, char **argv)
    3.40  {
    3.41 -	FILE *prn;
    3.42 +	pt_Device *dev;
    3.43 +
    3.44 +	pt_Image *im;
    3.45 +
    3.46 +	printf("create image\n");
    3.47 +	im = ptimage_Create(123, 456);
    3.48 +
    3.49 +	printf("delete image\n");
    3.50 +	ptimage_Free(im);
    3.51 +
    3.52 +	return 0;
    3.53  
    3.54  	// check command line args
    3.55  	if (argc < 2) {
    3.56 @@ -14,34 +51,16 @@
    3.57  		return -1;
    3.58  	}
    3.59  
    3.60 -	// open printer device
    3.61 -	if ((prn = fopen(argv[1], "r+b")) == NULL) {
    3.62 -		printf("ERROR: couldn't open printer device '%s'\n", argv[1]);
    3.63 +	// Open and initialise the printer
    3.64 +	dev = pt_Initialise(argv[1]);
    3.65 +
    3.66 +	if (dev == NULL) {
    3.67 +		printf("Error opening printer device.\n");
    3.68  		return -1;
    3.69  	}
    3.70  
    3.71 -	// INITIALISE
    3.72 -	fprintf(prn, "%c%c", ESC, '@');
    3.73 -
    3.74 -	// REQUEST STATUS
    3.75 -	fprintf(prn, "%c%c%c", ESC, 'i', 'S');
    3.76 +	// Close the printer device
    3.77 +	pt_Close(dev);
    3.78  
    3.79 -	// Read status buffer from printer
    3.80 -	unsigned char buf[32];
    3.81 -	int timeout = 128;
    3.82 -	do {
    3.83 -		fread(buf, 1, 32, prn);
    3.84 -	} while ((buf[0] != 0x80) && (timeout-- > 0));
    3.85 -
    3.86 -	if (timeout > 0) {
    3.87 -		printf("Printer status:\n");
    3.88 -		hex_dump(buf, 32);
    3.89 -	} else {
    3.90 -		printf("TIMEOUT\n");
    3.91 -		return -1;
    3.92 -	}
    3.93 -
    3.94 -	// Close the printer stream
    3.95 -	fclose(prn);
    3.96  	return 0;
    3.97  }
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/pt_image.c	Sat Aug 01 12:42:34 2009 +0100
     4.3 @@ -0,0 +1,130 @@
     4.4 +#include <stdio.h>
     4.5 +#include <stdlib.h>
     4.6 +#include <string.h>
     4.7 +#include "pt_image.h"
     4.8 +
     4.9 +/**
    4.10 + * Create a new pt_Image object.
    4.11 + *
    4.12 + * Creates a new pt_Image of a specified width and height, and initialises
    4.13 + * all the pixels in its buffer to zero.
    4.14 + *
    4.15 + * @param	width		The width of the image.
    4.16 + * @param	height		The height of the image.
    4.17 + * @return	The new pt_Image, or NULL on failure.
    4.18 + */
    4.19 +pt_Image *ptimage_Create(unsigned long width, unsigned long height)
    4.20 +{
    4.21 +	pt_Image *image;
    4.22 +
    4.23 +#ifdef DEBUG
    4.24 +	printf("%s[%d]: image size = %u\n", __FILE__, __LINE__, sizeof(pt_Image));
    4.25 +	printf("%s[%d]: data  size = %u\n", __FILE__, __LINE__, sizeof(image->data[0]));
    4.26 +	printf("%s[%d]: create %lu x %lu image\n", __FILE__, __LINE__, width, height);
    4.27 +#endif
    4.28 +
    4.29 +	// Allocate memory for the new image and its data buffer
    4.30 +	image = malloc(sizeof(pt_Image));
    4.31 +	if (image == NULL) return NULL;
    4.32 +
    4.33 +	image->data = malloc(width * height * sizeof(image->data[0]));
    4.34 +	if (image->data == NULL) return NULL;
    4.35 +
    4.36 +	// Set the image's parameters
    4.37 +	image->width = width;
    4.38 +	image->height = height;
    4.39 +
    4.40 +	// Clear the image's data buffer to "blank"
    4.41 +	memset(image->data, 0, width * height * sizeof(image->data[0]));
    4.42 +
    4.43 +	return image;
    4.44 +}
    4.45 +
    4.46 +/**
    4.47 + * Free a pt_Image object.
    4.48 + *
    4.49 + * @param	image		The image object to free.
    4.50 + */
    4.51 +void ptimage_Free(pt_Image *image)
    4.52 +{
    4.53 +	// Make sure image is non-null
    4.54 +	if (image == NULL) {
    4.55 +		return;
    4.56 +	}
    4.57 +
    4.58 +	// Free the image data
    4.59 +	if (image->data != NULL) {
    4.60 +		free(image->data);
    4.61 +	}
    4.62 +
    4.63 +	// Free the image
    4.64 +	free(image);
    4.65 +}
    4.66 +
    4.67 +/**
    4.68 + * Get the value of a pixel in a pt_Image object.
    4.69 + *
    4.70 + * @param	image		Image object.
    4.71 + * @param	x			X position of the pixel, zero-based.
    4.72 + * @param	y			Y position of the pixel, zero-based.
    4.73 + * @return	Value of the pixel, or negative on error.
    4.74 + */
    4.75 +int ptimage_GetPixel(pt_Image *image, unsigned long x, unsigned long y)
    4.76 +{
    4.77 +	// Make sure the image is not null and that the data buffer has been
    4.78 +	// allocated
    4.79 +	if (image == NULL) {
    4.80 +		return -1;	// TODO: make constant
    4.81 +	}
    4.82 +
    4.83 +	if (image->data == NULL) {
    4.84 +		return -1;	// TODO: make constant
    4.85 +	}
    4.86 +
    4.87 +	// Range-check
    4.88 +	if ((x < 0) || (x > image->width)) {
    4.89 +		return -2;	// TODO: make constant
    4.90 +	}
    4.91 +	if ((y < 0) || (y > image->height)) {
    4.92 +		return -3;	// TODO: make constant
    4.93 +	}
    4.94 +
    4.95 +	// Return the pixel value
    4.96 +	return image->data[(y*image->width)+x];
    4.97 +}
    4.98 +
    4.99 +/**
   4.100 + * Set the value of a pixel in a pt_Image object.
   4.101 + *
   4.102 + * @param	image		Image object.
   4.103 + * @param	x			X position of the pixel, zero-based.
   4.104 + * @param	y			Y position of the pixel, zero-based.
   4.105 + * @param	val			New value of the pixel.
   4.106 + * @return	Zero on success, or negative on error.
   4.107 + */
   4.108 +int ptimage_SetPixel(pt_Image *image, unsigned long x, unsigned long y, unsigned char val)
   4.109 +{
   4.110 +	// Make sure the image is not null and that the data buffer has been
   4.111 +	// allocated
   4.112 +	if (image == NULL) {
   4.113 +		return -1;	// TODO: make constant
   4.114 +	}
   4.115 +
   4.116 +	if (image->data == NULL) {
   4.117 +		return -1;	// TODO: make constant
   4.118 +	}
   4.119 +
   4.120 +	// Range-check
   4.121 +	if ((x < 0) || (x > image->width)) {
   4.122 +		return -2;	// TODO: make constant
   4.123 +	}
   4.124 +	if ((y < 0) || (y > image->height)) {
   4.125 +		return -3;	// TODO: make constant
   4.126 +	}
   4.127 +
   4.128 +	// Set the pixel value
   4.129 +	image->data[(y*image->width)+x] = val;
   4.130 +
   4.131 +	return 0;
   4.132 +}
   4.133 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/pt_image.h	Sat Aug 01 12:42:34 2009 +0100
     5.3 @@ -0,0 +1,20 @@
     5.4 +#ifndef PT_IMAGE_H
     5.5 +#define PT_IMAGE_H
     5.6 +
     5.7 +/**
     5.8 + * A storage class for simple images.
     5.9 + *
    5.10 + * Data is stored as bytes, as this makes the math easier (and modern
    5.11 + * computer systems have plenty of RAM anyway).
    5.12 + */
    5.13 +typedef struct {
    5.14 +	unsigned long	width, height;
    5.15 +	unsigned char	*data;
    5.16 +} pt_Image;
    5.17 +
    5.18 +pt_Image *ptimage_Create(unsigned long width, unsigned long height);
    5.19 +void ptimage_Free(pt_Image *image);
    5.20 +int ptimage_GetPixel(pt_Image *image, unsigned long x, unsigned long y);
    5.21 +int ptimage_SetPixel(pt_Image *image, unsigned long x, unsigned long y, unsigned char val);
    5.22 +
    5.23 +#endif	// PT_IMAGE_H
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/ptouch.c	Sat Aug 01 12:42:34 2009 +0100
     6.3 @@ -0,0 +1,129 @@
     6.4 +/****************************************************************************
     6.5 + * Project:   P-touch printer driver library
     6.6 + * Developer: Philip Pemberton
     6.7 + * Purpose:   Make Brother P-touch (PT-series) printers do something besides
     6.8 + *            gather dust.
     6.9 + *
    6.10 + *            Currently supports:
    6.11 + *              PT-2450DX
    6.12 + ****************************************************************************/
    6.13 +
    6.14 +// TODO: disable
    6.15 +#define DEBUG
    6.16 +
    6.17 +#include <stdio.h>
    6.18 +#include <stdlib.h>
    6.19 +#include <string.h>
    6.20 +#include "hexdump.h"
    6.21 +#include "pt_image.h"
    6.22 +#include "ptouch.h"
    6.23 +
    6.24 +#define ESC 0x1b
    6.25 +
    6.26 +pt_Device *pt_Initialise(char *path)
    6.27 +{
    6.28 +	pt_Device	*dev;
    6.29 +	FILE		*prn;
    6.30 +
    6.31 +	// Try and open the printer device
    6.32 +	prn = fopen(path, "r+b");
    6.33 +	if (prn == NULL) {
    6.34 +		return NULL;
    6.35 +	}
    6.36 +
    6.37 +	// Printer device open, send an init command and read the status
    6.38 +	fprintf(prn, "%c%c", ESC, '@');
    6.39 +
    6.40 +	// Allocate memory for the device block
    6.41 +	dev = malloc(sizeof(pt_Device));
    6.42 +	if (dev == NULL) {
    6.43 +		fclose(prn);
    6.44 +		return NULL;
    6.45 +	}
    6.46 +
    6.47 +	// Store the file pointer
    6.48 +	dev->fp = prn;
    6.49 +
    6.50 +	// Memory allocation OK, now get the printer's status
    6.51 +	if (pt_GetStatus(dev) == 0) {
    6.52 +		return dev;
    6.53 +	} else {
    6.54 +		free(dev);
    6.55 +		return NULL;
    6.56 +	}
    6.57 +}
    6.58 +
    6.59 +int pt_GetStatus(pt_Device *dev)
    6.60 +{
    6.61 +	// REQUEST STATUS
    6.62 +	fprintf(dev->fp, "%c%c%c", ESC, 'i', 'S');
    6.63 +
    6.64 +	// Read status buffer from printer
    6.65 +	unsigned char buf[32];
    6.66 +	int timeout = 128;
    6.67 +	do {
    6.68 +		fread(buf, 1, 32, dev->fp);
    6.69 +	} while ((buf[0] != 0x80) && (timeout-- > 0));
    6.70 +
    6.71 +	// Check for timeout
    6.72 +	if (timeout == 0) {
    6.73 +		// Timeout
    6.74 +		return -1;
    6.75 +	}
    6.76 +
    6.77 +#ifdef DEBUG
    6.78 +	printf("DEBUG: Printer status buffer = \n");
    6.79 +	hex_dump(buf, 32);
    6.80 +#endif
    6.81 +
    6.82 +	// Decode the status buffer, store the results in the device object
    6.83 +	dev->headMark     = buf[0];
    6.84 +	dev->size         = buf[1];
    6.85 +	dev->errorInfo[0] = buf[8];
    6.86 +	dev->errorInfo[1] = buf[9];
    6.87 +	dev->mediaWidth   = buf[10];
    6.88 +	dev->mediaType    = buf[11];
    6.89 +	dev->mediaLength  = buf[17];
    6.90 +	dev->statusType   = buf[18];
    6.91 +	dev->phaseType    = buf[19];
    6.92 +	dev->phaseHi      = buf[20];
    6.93 +	dev->phaseLo      = buf[21];
    6.94 +	dev->notification = buf[22];
    6.95 +
    6.96 +	// Operation succeeded
    6.97 +	return 0;
    6.98 +}
    6.99 +
   6.100 +// TODO: print options struct parameter (e.g. fullcut, halfcut, print res,
   6.101 +//
   6.102 +int pt_Print(pt_Device *dev, pt_Image *image)
   6.103 +{
   6.104 +	// TODO: trap dev == NULL
   6.105 +	// TODO: trap image == NULL
   6.106 +	// TODO: trap image.height > printhead.height
   6.107 +	// TODO: trap image.height <= 0
   6.108 +	// TODO: trap image.width <= 0
   6.109 +	//
   6.110 +	// allocate print buffer
   6.111 +	//
   6.112 +	// pack pixels -- 8 pixels => 1 byte
   6.113 +	//
   6.114 +	// compress print data (packbits)
   6.115 +	//
   6.116 +	// send print buffer to printer
   6.117 +	//
   6.118 +	// free print buffer
   6.119 +}
   6.120 +
   6.121 +void pt_Close(pt_Device *dev)
   6.122 +{
   6.123 +	// Sanity check -- make sure dev is not null
   6.124 +	if (dev == NULL) return;
   6.125 +
   6.126 +	// Close the printer stream
   6.127 +	fclose(dev->fp);
   6.128 +
   6.129 +	// Release the memory allocated to the status buffer
   6.130 +	free(dev);
   6.131 +}
   6.132 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/ptouch.h	Sat Aug 01 12:42:34 2009 +0100
     7.3 @@ -0,0 +1,27 @@
     7.4 +/****************************************************************************
     7.5 + * Project:   P-touch printer driver library
     7.6 + * Developer: Philip Pemberton
     7.7 + * Purpose:   Make Brother P-touch (PT-series) printers do something besides
     7.8 + *            gather dust.
     7.9 + *
    7.10 + *            Currently supports:
    7.11 + *              PT-2450DX
    7.12 + ****************************************************************************/
    7.13 +
    7.14 +#ifndef PTOUCH_H
    7.15 +#define PTOUCH_H
    7.16 +
    7.17 +typedef struct {
    7.18 +	FILE	*fp;
    7.19 +	int		headMark, size, errorInfo[2];
    7.20 +	int		mediaWidth, mediaType, mediaLength;
    7.21 +	int		statusType, phaseType, phaseHi, phaseLo;
    7.22 +	int		notification;
    7.23 +} pt_Device;
    7.24 +
    7.25 +// printer functions
    7.26 +pt_Device *pt_Initialise(char *path);
    7.27 +int pt_GetStatus(pt_Device *dev);
    7.28 +void pt_Close(pt_Device *dev);
    7.29 +
    7.30 +#endif // PTOUCH_H