public static ByteArrayOutputStream preprocess(final InputStream is, final StringBuilder firstComment, final Map<String, String> defines)
            throws IOException, ImagingException {
        boolean inSingleQuotes = false;
        boolean inString = false;
        boolean inComment = false;
        boolean inDirective = false;
        boolean hadSlash = false;
        boolean hadStar = false;
        boolean hadBackSlash = false;
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        boolean seenFirstComment = firstComment == null;
        final StringBuilder directiveBuffer = new StringBuilder();
        for (int c = is.read(); c != -1; c = is.read()) {
            if (inComment) {
                if (c == '*') {
                    if (hadStar && !seenFirstComment) {
                        firstComment.append('*');
                    }
                    hadStar = true;
                } else if (c == '/') {
                    if (hadStar) {
                        hadStar = false;
                        inComment = false;
                        seenFirstComment = true;
                    } else if (!seenFirstComment) {
                        firstComment.append((char) c);
                    }
                } else {
                    if (hadStar && !seenFirstComment) {
                        firstComment.append('*');
                    }
                    hadStar = false;
                    if (!seenFirstComment) {
                        firstComment.append((char) c);
                    }
                }
            } else if (inSingleQuotes) {
                switch (c) {
                case '\\':
                    if (hadBackSlash) {
                        out.write('\\');
                        out.write('\\');
                        hadBackSlash = false;
                    } else {
                        hadBackSlash = true;
                    }
                    break;
                case '\'':
                    if (hadBackSlash) {
                        out.write('\\');
                        hadBackSlash = false;
                    } else {
                        inSingleQuotes = false;
                    }
                    out.write('\'');
                    break;
                case '\r':
                case '\n':
                    throw new ImagingException("Unterminated single quote in file");
                default:
                    if (hadBackSlash) {
                        out.write('\\');
                        hadBackSlash = false;
                    }
                    out.write(c);
                    break;
                }
            } else if (inString) {
                switch (c) {
                case '\\':
                    if (hadBackSlash) {
                        out.write('\\');
                        out.write('\\');
                        hadBackSlash = false;
                    } else {
                        hadBackSlash = true;
                    }
                    break;
                case '"':
                    if (hadBackSlash) {
                        out.write('\\');
                        hadBackSlash = false;
                    } else {
                        inString = false;
                    }
                    out.write('"');
                    break;
                case '\r':
                case '\n':
                    throw new ImagingException("Unterminated string in file");
                default:
                    if (hadBackSlash) {
                        out.write('\\');
                        hadBackSlash = false;
                    }
                    out.write(c);
                    break;
                }
            } else if (inDirective) {
                if (c == '\r' || c == '\n') {
                    inDirective = false;
                    final String[] tokens = tokenizeRow(directiveBuffer.toString());
                    if (tokens.length < 2 || tokens.length > 3) {
                        throw new ImagingException("Bad preprocessor directive");
                    }
                    if (!tokens[0].equals("define")) {
                        throw new ImagingException("Invalid/unsupported " + "preprocessor directive '" + tokens[0] + "'");
                    }
                    defines.put(tokens[1], tokens.length == 3 ? tokens[2] : null);
                    directiveBuffer.setLength(0);
                } else {
                    directiveBuffer.append((char) c);
                }
            } else {
                switch (c) {
                case '/':
                    if (hadSlash) {
                        out.write('/');
                    }
                    hadSlash = true;
                    break;
                case '*':
                    if (hadSlash) {
                        inComment = true;
                        hadSlash = false;
                    } else {
                        out.write(c);
                    }
                    break;
                case '\'':
                    if (hadSlash) {
                        out.write('/');
                    }
                    hadSlash = false;
                    out.write(c);
                    inSingleQuotes = true;
                    break;
                case '"':
                    if (hadSlash) {
                        out.write('/');
                    }
                    hadSlash = false;
                    out.write(c);
                    inString = true;
                    break;
                case '#':
                    if (defines == null) {
                        throw new ImagingException("Unexpected preprocessor directive");
                    }
                    inDirective = true;
                    break;
                default:
                    if (hadSlash) {
                        out.write('/');
                    }
                    hadSlash = false;
                    out.write(c);
                    // Only whitespace allowed before first comment:
                    if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                        seenFirstComment = true;
                    }
                    break;
                }
            }
        }
        if (hadSlash) {
            out.write('/');
        }
        if (hadStar) {
            out.write('*');
        }
        if (inString) {
            throw new ImagingException("Unterminated string at the end of file");
        }
        if (inComment) {
            throw new ImagingException("Unterminated comment at the end of file");
        }
        return out;
    }
Parses the {@code i:th} escape-char in the input {@code string} and appends it to {@code stringBuilder}.

<p>
Helper-function for {@code unescapeString()}.
</p>

@param i             the index of the escape-char in the string
@param stringBuilder the stringBuilder to append the escape-char to
@param string        the string whose chars are parsed
@return the new index i
@since 1.0-alpha3
src/main/java/org/apache/commons/imaging/common/BasicCParser.java