private CucaDiagramFileMakerResult createPng(OutputStream os, List<String> dotStrings,
			FileFormatOption fileFormatOption) throws IOException, InterruptedException {

		final StringBuilder cmap = new StringBuilder();
		double supX = 0;
		double supY = 0;
		try {
			final GraphvizMaker dotMaker = populateImagesAndCreateGraphvizMaker(dotStrings, fileFormatOption);
			final String dotString = dotMaker.createDotString();

			if (OptionFlags.getInstance().isKeepTmpFiles()) {
				traceDotString(dotString);
			}

			final byte[] imageData = getImageData(dotString, cmap);

			if (imageData.length == 0) {
				createError(os, imageData.length, new FileFormatOption(FileFormat.PNG), "imageData.length == 0");
				return null;
			}

			if (isPngHeader(imageData, 0) == false) {
				createError(os, imageData.length, new FileFormatOption(FileFormat.PNG), "No PNG header found",
						"Try -forcegd or -forcecairo flag");
				return null;
			}

			final ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
			BufferedImage im = ImageIO.read(bais);
			if (im == null) {
				createError(os, imageData.length, new FileFormatOption(FileFormat.PNG), "im == null");
				return null;
			}
			bais.close();
			dotMaker.clean();

			final boolean isUnderline = dotMaker.isUnderline();
			if (isUnderline) {
				new UnderlineTrick(im, new Color(Integer.parseInt("FEFECF", 16)), Color.BLACK).process();
			}

			final HtmlColor background = diagram.getSkinParam().getBackgroundColor();

			supY = getTitlePngHeight(stringBounder);
			supY += getHeaderPngHeight(stringBounder);

			supX = getOffsetX(stringBounder, im.getWidth());

			im = addTitle(im, background);
			im = addFooter(im, background);
			im = addHeader(im, background);
			im = scaleImage(im, diagram.getScale());

			if (diagram.isRotation()) {
				im = PngRotation.process(im);
			}
			im = PngSizer.process(im, diagram.getMinwidth());

			im = addFlashcode(im, diagram.getColorMapper().getMappedColor(background));

			PngIO.write(im, os, diagram.getMetadata(), diagram.getDpi(fileFormatOption));
		} finally {
			clean();
		}

		if (cmap.length() > 0) {
			return new CucaDiagramFileMakerResult(translateXY(cmap.toString(), (int) Math.round(supX),
					(int) Math.round(supY)));
		}
		return null;
	}