private void mutate(COSBase obj) throws IOException {

        //stub
        if (obj instanceof COSStream) {
            COSStream stream = (COSStream) obj;
            //get the raw unfiltered bytes
            byte[] bytes = new PDStream(stream).toByteArray();
            //transform the underlying stream _before_ filters are applied
            if (config.getStreamTransformer() != null) {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                try {
                    config.getStreamTransformer().transform(new ByteArrayInputStream(bytes), bos);
                } catch (TikaException e) {
                    throw new IOException(e);
                }
                bytes = bos.toByteArray();
            }
            COSBase filters = getFilters(stream.getFilters());
            if (filters instanceof COSNull) {
                stream.removeItem(COSName.FILTER);
            } else {
                List<COSName> usedFilters = new ArrayList<>();
                long length = -1;
                try (TikaInputStream rawBytes = TikaInputStream.get(bytes)) {
                    try (TikaInputStream filtered = runFilters(filters, rawBytes, usedFilters)) {
                        //rewrite raw bytes after running own filters
                        try (OutputStream streamOut = stream.createRawOutputStream()) {
                            IOUtils.copy(filtered, streamOut);
                        }
                        length = filtered.getLength();
                    }
                }
                Collections.reverse(usedFilters);
                COSArray actualFilters = new COSArray();
                for (COSName f : usedFilters) {
                    actualFilters.add(f);
                }
                //TODO: parameterize wonkifying length and filters
                stream.setLong(COSName.LENGTH, length);
                stream.setItem(COSName.FILTER, actualFilters);
            }
        } else if (obj instanceof COSObject) {
            COSBase underlyingObject = ((COSObject) obj).getObject();
            mutate(underlyingObject);

        }
    }
This will write the body of the document.

@param doc The document to write the body for.
@throws IOException If there is an error writing the data.
tika-fuzzing/src/main/java/org/apache/tika/fuzzing/pdf/EvilCOSWriter.java