public bool SHEQPrintSDSLabel(clsLabelDetails label, labelprinterdrivers driver, string OSprintername, int number_of_copies)
        {
            bool inverse_images;

            /* idle? */
            if (number_of_copies <= 0)
            {
                return(true);
            }
            try
            {
                /* does the driver exist? */
                if (driver == labelprinterdrivers.lpd_zebratlp2844_orange)
                {
                    inverse_images = false;
                }
                else if (driver == labelprinterdrivers.lpd_zebratlp2844_white)
                {
                    inverse_images = true;
                }
                else
                {
                    /* format not supported */
                    throw new ArgumentOutOfRangeException("driver", driver, "The label format specified is not supported by this version of the printer driver.");
                }
                /* treat the pictures */
                int      ctpictures  = 0;
                Bitmap[] pictures    = new Bitmap[max_pics_per_label];
                Bitmap[] monochromes = new Bitmap[max_pics_per_label];
                byte[][] rasters     = new byte[max_pics_per_label][] { new byte[] { }, new byte[] { }, new byte[] { } };
                if (label.Pictures == null)
                {
                    ctpictures = 0;
                }
                else
                {
                    ctpictures = label.Pictures.Length;
                }
                if (ctpictures > max_pics_per_label)
                {
                    /* too many pictures */
                    throw new ArgumentOutOfRangeException("ctpictures", ctpictures, "This layout does not permit to print more than three pictures on a form.");
                }
                else
                {
                    /* make them smoothly smaller */
                    for (int i = 0; i < ctpictures; ++i)
                    {
                        pictures[i] = new Bitmap(160, 160, PixelFormat.Format24bppRgb);
                        using (var gfxX = Graphics.FromImage(pictures[i]))
                        {
                            gfxX.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            gfxX.DrawImage(label.Pictures[i], new Rectangle(0, 0, 160, 160), 0, 0, label.Pictures[i].Width, label.Pictures[i].Height, GraphicsUnit.Pixel);
                        }
                    }
                }
                /* convert any pictures we got */
                for (int i = 0; i < ctpictures; ++i)
                {
                    /* a. increase brightness */
                    for (int y = 0; y < pictures[i].Height; ++y)
                    {
                        for (int x = 0; x < pictures[i].Width; ++x)
                        {
                            if (pictures[i].GetPixel(x, y).GetBrightness() > 0)
                            {
                                pictures[i].SetPixel(x, y, Color.White);
                            }
                        }
                    }
                    /* b. from color to monochrome */
                    monochromes[i] = CopyToBpp(pictures[i], 1);
                    /* c. from bmp to EPL raster */
                    rasters[i] = BitmapToEPLRaster(monochromes[i], inverse_images);
                }
                /* compose the EPL sequence */
                const int    width  = 800;
                const int    height = 560;
                clsEPLDriver epl    = new clsEPLDriver();
                epl.LabelStart(height, 19, width, "A", 49);
                /* 1. print the header */
                epl.LabelText(30, 8, 0, 2, 1, 1, false, label.Clientcompany);
                epl.LabelTextRAlign(773, 8, 0, 2, 1, 1, false, label.Clientbusiness);
                epl.LabelLine(30, 25, 743, 3);
                /* 2. print the substance name */
                int ypos       = 50;
                int lineheight = epl.TextHeight(4, 2, 3, label.Name);
                epl.Font            = 4;
                epl.MultiplierHoriz = 2;
                epl.MultiplierVert  = 3;
                var renderer = new clsWordbreaker();
                renderer.JustifyText(label.Name, epl, new Rectangle(10, ypos, width - 20, lineheight * 2));
#if DEBUG
                //epl.LabelLine(10,ypos+10,width-20,10);
#endif
                ypos += renderer.effHeight;
                /* 3. print the manufacturer */
                epl.LabelTextHCenter(width / 2, ypos, 0, 4, 1, 2, false, label.Manufacturer);

                /* frameborder for debugging purposes:
                 *  epl.LabelLine(0,0,width,20);
                 *  epl.LabelLine(0,height-20,width,20);
                 *  epl.LabelLine(0,0,20,height);
                 *  epl.LabelLine(width-20,0,20,height);
                 */
                /* 4. fill the orange rectangles with the pictures and their subscripts */
                epl.Font            = 1;
                epl.MultiplierHoriz = 1;
                epl.MultiplierVert  = 1;
                int posfact = 225;
                int posofst = 92;
                for (int i = 0; i < ctpictures; ++i)
                {
                    int xco = posofst + i * posfact;
                    epl.LabelBitmap(
                        xco,
                        315,
                        rasters[i],
                        monochromes[i].Width / 8
                        );
                    lineheight = epl.TextHeight(1, 1, 1, label.Subscripts[i]);
                    renderer   = new clsWordbreaker();
                    renderer.JustifyText(label.Subscripts[i], epl, new Rectangle(xco, 480, monochromes[i].Width, lineheight * 2));
                }
                epl.LabelEnd(number_of_copies);
                /* send to the printer */
                byte[] sequence = epl.ToPrinter;
                int    hresult;
                bool   result = clsDirectPrinting.SendByteArrayToPrinter(OSprintername, label.Name, sequence, out hresult);
                /* evaluate the result */
                if (result)
                {
                    return(true);
                }
                else
                {
                    throw new Exception(String.Format("An error occurred whilst sending the print job \"{0}\" to the device \"{1}\".", label.Name, OSprintername));
                }
            }
            catch (Exception ex)
            {
                /* some error */
                throw new Exception(String.Format("An error occurred whilst preparing the print job \"{0}\".", label.Name), ex);
            }
        }
        /// <summary>
        /// Prints a label to TCP address "this.TargetFilename"
        /// </summary>
        protected override bool RenderInternal(ref MemoryStream chunk, out string mime)
        {
            Debug.Assert(Outputtarget == ReportTarget.Printer);

            /* this does not return anything. it sends the data directly to the printer.
             * this is a deviation from the standard procedere where, usually, the caller
             * of the report would be responsible for streaming the result of the report
             * generator's rendition to the user */
            mime  = null;
            chunk = null;
            try
            {
                /* 1. get the details about the substance which the printer driver needs */
                var dt    = Data.Tables[ReportDatatableIdentifiers.REPORT_DATATABLE_CLP_LABEL].Rows[0];
                var label = new labelprinter.clsLabelDetails()
                {
                    Clientcompany  = dt["Clientcompany"].ToString(),
                    Clientbusiness = dt["Clientbusiness"].ToString(),
                    Name           = dt["Caption"].ToString(),                                        /* [dlatikay 20130709] had been missing */
                    Hazardous      = String.IsNullOrWhiteSpace(dt["Signalword"].ToString()) == false, /* DL20130705D72238J */
                    Manufacturer   = dt["SupplierName"].ToString()
                };
                /* add the picture information to the label data set */
                var pics     = Data.Tables[ReportDatatableIdentifiers.REPORT_DATATABLE_CLP_LABELPICS].Rows;
                var streams  = new List <MemoryStream>();
                var images   = new List <Image>();
                var captions = new List <string>();
                try
                {
                    foreach (DataRow dr in pics)
                    {
                        var stream = new MemoryStream((byte[])dr["Image"], false);
                        streams.Add(stream); /* important: GDI+ wants access to the underlying source stream as long as it keeps working on the image */
                        var img = Image.FromStream(stream);
                        images.Add(img);
                        captions.Add(dr["Subscript"].ToString());
                    }
                    label.Pictures   = images.ToArray();
                    label.Subscripts = captions.ToArray();
                    /* 2. initiate layouting and submission to printer port */
                    var drv = new labelprinter.clsLabelprinting();
                    drv.SHEQPrintSDSLabel(label, labelprinter.labelprinterdrivers.lpd_zebratlp2844_orange, this.TargetFilename, 1);
                }
                finally
                {
                    foreach (var img in images)
                    {
                        if (img != null)
                        {
                            img.Dispose();
                        }
                    }
                    foreach (var stream in streams)
                    {
                        if (stream != null)
                        {
                            stream.Dispose();
                        }
                    }
                }
                /* succeeded */
                return(true);
            }
            catch (Exception ex)
            {
                /* some error */
                OnBuiltinReportError(ex.Message, ex);
                return(false);
            }
        }